diff --git a/com.ibm.wala.core.testdata/.classpath b/com.ibm.wala.core.testdata/.classpath new file mode 100644 index 000000000..021596729 --- /dev/null +++ b/com.ibm.wala.core.testdata/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/com.ibm.wala.core.testdata/.project b/com.ibm.wala.core.testdata/.project new file mode 100644 index 000000000..3929f7404 --- /dev/null +++ b/com.ibm.wala.core.testdata/.project @@ -0,0 +1,28 @@ + + + com.ibm.wala.core.testdata + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/com.ibm.wala.core.testdata/.settings/org.eclipse.jdt.ui.prefs b/com.ibm.wala.core.testdata/.settings/org.eclipse.jdt.ui.prefs new file mode 100644 index 000000000..a6c005a5a --- /dev/null +++ b/com.ibm.wala.core.testdata/.settings/org.eclipse.jdt.ui.prefs @@ -0,0 +1,3 @@ +#Tue Oct 17 11:41:36 EDT 2006 +eclipse.preferences.version=1 +internal.default.compliance=default diff --git a/com.ibm.wala.core.testdata/META-INF/MANIFEST.MF b/com.ibm.wala.core.testdata/META-INF/MANIFEST.MF new file mode 100644 index 000000000..728fa09a5 --- /dev/null +++ b/com.ibm.wala.core.testdata/META-INF/MANIFEST.MF @@ -0,0 +1,7 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Testdata Plug-in +Bundle-SymbolicName: com.ibm.wala.core.testdata +Bundle-Version: 1.0.0 +Bundle-Vendor: IBM +Bundle-Localization: plugin diff --git a/com.ibm.wala.core.testdata/build.properties b/com.ibm.wala.core.testdata/build.properties new file mode 100644 index 000000000..41eb6ade2 --- /dev/null +++ b/com.ibm.wala.core.testdata/build.properties @@ -0,0 +1,4 @@ +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + . diff --git a/com.ibm.wala.core.testdata/build.xml b/com.ibm.wala.core.testdata/build.xml new file mode 100644 index 000000000..dd24b6fe3 --- /dev/null +++ b/com.ibm.wala.core.testdata/build.xml @@ -0,0 +1,150 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/com.ibm.wala.core.testdata/scripts/cruise/config_nashira.xml b/com.ibm.wala.core.testdata/scripts/cruise/config_nashira.xml new file mode 100644 index 000000000..c181613d7 --- /dev/null +++ b/com.ibm.wala.core.testdata/scripts/cruise/config_nashira.xml @@ -0,0 +1,229 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/com.ibm.wala.core.testdata/scripts/fetch.sh b/com.ibm.wala.core.testdata/scripts/fetch.sh new file mode 100644 index 000000000..023941426 --- /dev/null +++ b/com.ibm.wala.core.testdata/scripts/fetch.sh @@ -0,0 +1,55 @@ +#!/bin/bash +# +# Fetch source files or builds needed for wala.core regression tests +# +# + +fetch_jlex() { + echo "Fetching jlex ..."; + makeTempFolder; + cd tmp; + mkdir JLex; + cd JLex; + wget http://www.cs.princeton.edu/~appel/modern/java/JLex/current/Main.java; + javac Main.java; + cd ..; + jar cvf JLex.jar JLex; + mv JLex.jar ../../bin; + cd ..; + removeTempFolder; +} + +fetch_javacup() { + echo "Fetching java-cup..."; + makeTempFolder; + cd tmp; + wget http://www2.cs.tum.edu/projects/cup/java-cup-11a.jar; + mv java-cup-11a.jar ../../bin; + cd ..; + removeTempFolder; +} + +fetch_bcel() { + echo "Fetching bcel ..."; + makeTempFolder; + cd tmp; + wget http://www.apache.org/dist/jakarta/bcel/binaries/bcel-5.2.tar.gz; + gunzip -c bcel-5.2.tar.gz | tar xvf - ; + mv bcel-5.2/bcel-5.2.jar ../../bin; + cd ..; + removeTempFolder; +} + +makeTempFolder() { + echo "Creating tmp/"; + mkdir tmp; +} + +removeTempFolder() { + echo "Removing tmp/"; + rm -rf tmp; +} + +fetch_bcel; +fetch_jlex; +fetch_javacup; diff --git a/com.ibm.wala.core.testdata/src/classConstant/ClassConstant.java b/com.ibm.wala.core.testdata/src/classConstant/ClassConstant.java new file mode 100644 index 000000000..d434626b4 --- /dev/null +++ b/com.ibm.wala.core.testdata/src/classConstant/ClassConstant.java @@ -0,0 +1,10 @@ +package classConstant; + +class ClassConstant { + + public static void main(String args[]) { + Class x = ClassConstant.class; + x.hashCode(); + } + +} diff --git a/com.ibm.wala.core.testdata/src/cornerCases/Abstract1.java b/com.ibm.wala.core.testdata/src/cornerCases/Abstract1.java new file mode 100644 index 000000000..5e1b96852 --- /dev/null +++ b/com.ibm.wala.core.testdata/src/cornerCases/Abstract1.java @@ -0,0 +1,17 @@ +//Licensed Materials - Property of IBM +//5724-D15 +//(C) Copyright IBM Corporation 2004. All Rights Reserved. +//Note to U.S. Government Users Restricted Rights: Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp. +// +//--------------------------------------------------------------------------- + +package cornerCases; + +/** + * @author sfink + * + */ +public abstract class Abstract1 { + + void foo() {} +} diff --git a/com.ibm.wala.core.testdata/src/cornerCases/Abstract2.java b/com.ibm.wala.core.testdata/src/cornerCases/Abstract2.java new file mode 100644 index 000000000..0555410e3 --- /dev/null +++ b/com.ibm.wala.core.testdata/src/cornerCases/Abstract2.java @@ -0,0 +1,17 @@ +//Licensed Materials - Property of IBM +//5724-D15 +//(C) Copyright IBM Corporation 2004. All Rights Reserved. +//Note to U.S. Government Users Restricted Rights: Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp. +// +//--------------------------------------------------------------------------- + +package cornerCases; + +/** + * @author sfink + * + */ +public abstract class Abstract2 { + + void foo() {} +} diff --git a/com.ibm.wala.core.testdata/src/cornerCases/Concrete2.java b/com.ibm.wala.core.testdata/src/cornerCases/Concrete2.java new file mode 100644 index 000000000..2eb7ff8d3 --- /dev/null +++ b/com.ibm.wala.core.testdata/src/cornerCases/Concrete2.java @@ -0,0 +1,16 @@ +//Licensed Materials - Property of IBM +//5724-D15 +//(C) Copyright IBM Corporation 2004. All Rights Reserved. +//Note to U.S. Government Users Restricted Rights: Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp. +// +//--------------------------------------------------------------------------- + +package cornerCases; + +/** + * @author sfink + * + */ +public class Concrete2 extends Abstract2 { + +} diff --git a/com.ibm.wala.core.testdata/src/cornerCases/Locals.java b/com.ibm.wala.core.testdata/src/cornerCases/Locals.java new file mode 100644 index 000000000..5389f9e12 --- /dev/null +++ b/com.ibm.wala.core.testdata/src/cornerCases/Locals.java @@ -0,0 +1,22 @@ +//Licensed Materials - Property of IBM +//5724-D15 +//(C) Copyright IBM Corporation 2004. All Rights Reserved. +//Note to U.S. Government Users Restricted Rights: Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp. +// +//--------------------------------------------------------------------------- + +package cornerCases; + +/** + * @author sfink + * + * Simple input test for local variable table + */ +public class Locals { + + public static void foo(String[] a) { + System.out.println(a); + Object b = a; + System.out.println(b); + } +} diff --git a/com.ibm.wala.core.testdata/src/cornerCases/Main.java b/com.ibm.wala.core.testdata/src/cornerCases/Main.java new file mode 100644 index 000000000..6b61b9be6 --- /dev/null +++ b/com.ibm.wala.core.testdata/src/cornerCases/Main.java @@ -0,0 +1,53 @@ +/******************************************************************************* + * 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 cornerCases; + +import sun.java2d.FontSupport; + +/** + * @author sfink + * + * TODO To change the template for this generated type comment go to + * Window - Preferences - Java - Code Style - Code Templates + */ +public class Main { + + public static void main(String[] args) { + testCastToString(); + } + + /** + * Test bug 38496: propagation of a string constant to a checkcast + */ + private static void testCastToString() { + Object o = "a constant string"; + String s = (String)o; + s.toString(); + } + + public static class YuckyField { + FontSupport f; + } + + /** + * Bug 38540: type inference crashed on this method when class + * FontSupport was not found + */ + public static Object foo() { + getFontSupport(); + return new YuckyField().f; + } + + public static FontSupport getFontSupport() { + return null; + } +} diff --git a/com.ibm.wala.core.testdata/src/cornerCases/YuckyInterface.java b/com.ibm.wala.core.testdata/src/cornerCases/YuckyInterface.java new file mode 100644 index 000000000..e4a421192 --- /dev/null +++ b/com.ibm.wala.core.testdata/src/cornerCases/YuckyInterface.java @@ -0,0 +1,21 @@ +//Licensed Materials - Property of IBM +//5724-D15 +//(C) Copyright IBM Corporation 2004. All Rights Reserved. +//Note to U.S. Government Users Restricted Rights: Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp. +// +//--------------------------------------------------------------------------- + +package cornerCases; + +import sun.java2d.FontSupport; + +/** + * @author sfink + * + * When analyzed with J2EEClassHierarchy exclusions, the superinterface + * FontSupport should not be found because we exclude sun.java2d.* + */ +public interface YuckyInterface extends FontSupport { + + +} diff --git a/com.ibm.wala.core.testdata/src/hello/Hello.java b/com.ibm.wala.core.testdata/src/hello/Hello.java new file mode 100644 index 000000000..6af153f01 --- /dev/null +++ b/com.ibm.wala.core.testdata/src/hello/Hello.java @@ -0,0 +1,22 @@ +/******************************************************************************* + * Copyright (c) 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 hello; + +public class Hello { + + /** + * @param args + */ + public static void main(String[] args) { + System.out.println("Hello world"); + } + +} diff --git a/com.ibm.wala.core.testdata/src/messageFormatTest/MessageFormatBench.java b/com.ibm.wala.core.testdata/src/messageFormatTest/MessageFormatBench.java new file mode 100644 index 000000000..c1b2865b9 --- /dev/null +++ b/com.ibm.wala.core.testdata/src/messageFormatTest/MessageFormatBench.java @@ -0,0 +1,23 @@ +/******************************************************************************* + * Copyright (c) 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 messageFormatTest; + +import java.text.MessageFormat; + +public class MessageFormatBench { + public static void main(String[] args) { + Object[] testArgs = {new Long(3), "MyDisk"}; + MessageFormat form = new MessageFormat("The disk \"{1}\" contains {0} file(s)."); + MessageFormat form2 = (MessageFormat) form.clone(); + System.out.println(form2.format(testArgs)); + } + +} diff --git a/com.ibm.wala.core.testdata/src/multiDim/TestMultiDim.java b/com.ibm.wala.core.testdata/src/multiDim/TestMultiDim.java new file mode 100644 index 000000000..9977b1235 --- /dev/null +++ b/com.ibm.wala.core.testdata/src/multiDim/TestMultiDim.java @@ -0,0 +1,18 @@ +package multiDim; + +public class TestMultiDim { + + static void doNothing(Object o) {} + + public static void main(String[] args) { + Object[][] multi = new Object[10][]; + multi[0] = new Object[10]; + testMulti(multi); + } + + static void testMulti(Object[][] multi) { + Object[] t = multi[0]; + doNothing(t); + } + +} \ No newline at end of file diff --git a/com.ibm.wala.core.testdata/src/pi/PiNodeCallGraphTestCase.java b/com.ibm.wala.core.testdata/src/pi/PiNodeCallGraphTestCase.java new file mode 100644 index 000000000..900fe8345 --- /dev/null +++ b/com.ibm.wala.core.testdata/src/pi/PiNodeCallGraphTestCase.java @@ -0,0 +1,72 @@ +/******************************************************************************* + * Copyright (c) 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 pi; + +class PiNodeCallGraphTestCase { + + interface Whatever { + + void unary1(); + + void unary2(); + + void binary(Whatever arg); + + } + + static class This implements Whatever { + + public void unary1() { + unary2(); + } + + public void unary2() { + + } + + public void binary(Whatever arg) { + this.unary1(); + arg.unary2(); + } + + } + + static class That implements Whatever { + + public void unary1() { + + } + + public void unary2() { + unary1(); + } + + public void binary(Whatever arg) { + this.unary1(); + arg.unary2(); + } + + } + + public native static boolean choice(); + + public static void main(String[] args) { + Whatever x = new This(); + Whatever y = new That(); + Whatever z = choice()? x: y; + + if (z instanceof This) + x.binary(z); + else + y.binary(z); + } + +} diff --git a/com.ibm.wala.core.testdata/src/recurse/NList.java b/com.ibm.wala.core.testdata/src/recurse/NList.java new file mode 100644 index 000000000..e74adde8e --- /dev/null +++ b/com.ibm.wala.core.testdata/src/recurse/NList.java @@ -0,0 +1,142 @@ +/******************************************************************************* + * Copyright (c) 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 recurse; + +import java.util.Collection; +import java.util.Iterator; + +/** + * @author sfink + * + * A simple exercise in recursive data structures. + */ +public class NList implements Collection { + + final int value; + final NList next; + + public NList(int value) { + this.value = value; + if (value > 0) { + this.next = new NList(value - 1); + } else { + this.next = null; + } + } + + + public static void main(String[] args) { + new NList(100); + } + + /* (non-Javadoc) + * @see java.util.Collection#size() + */ + public int size() { + // TODO Auto-generated method stub + return 0; + } + + /* (non-Javadoc) + * @see java.util.Collection#isEmpty() + */ + public boolean isEmpty() { + // TODO Auto-generated method stub + return false; + } + + /* (non-Javadoc) + * @see java.util.Collection#contains(java.lang.Object) + */ + public boolean contains(Object o) { + // TODO Auto-generated method stub + return false; + } + + /* (non-Javadoc) + * @see java.util.Collection#iterator() + */ + public Iterator iterator() { + // TODO Auto-generated method stub + return null; + } + + /* (non-Javadoc) + * @see java.util.Collection#toArray() + */ + public Object[] toArray() { + // TODO Auto-generated method stub + return null; + } + + + /* (non-Javadoc) + * @see java.util.Collection#add(java.lang.Object) + */ + public boolean add(Object o) { + // TODO Auto-generated method stub + return false; + } + + /* (non-Javadoc) + * @see java.util.Collection#remove(java.lang.Object) + */ + public boolean remove(Object o) { + // TODO Auto-generated method stub + return false; + } + + /* (non-Javadoc) + * @see java.util.Collection#containsAll(java.util.Collection) + */ + public boolean containsAll(Collection c) { + // TODO Auto-generated method stub + return false; + } + + /* (non-Javadoc) + * @see java.util.Collection#addAll(java.util.Collection) + */ + public boolean addAll(Collection c) { + // TODO Auto-generated method stub + return false; + } + + /* (non-Javadoc) + * @see java.util.Collection#removeAll(java.util.Collection) + */ + public boolean removeAll(Collection c) { + // TODO Auto-generated method stub + return false; + } + + /* (non-Javadoc) + * @see java.util.Collection#retainAll(java.util.Collection) + */ + public boolean retainAll(Collection c) { + // TODO Auto-generated method stub + return false; + } + + /* (non-Javadoc) + * @see java.util.Collection#clear() + */ + public void clear() { + // TODO Auto-generated method stub + + } + + + public Object[] toArray(Object[] a) { + // TODO Auto-generated method stub + return null; + } +} diff --git a/com.ibm.wala.core.testdata/src/reflection/Reflect1.java b/com.ibm.wala.core.testdata/src/reflection/Reflect1.java new file mode 100644 index 000000000..6bb15e103 --- /dev/null +++ b/com.ibm.wala.core.testdata/src/reflection/Reflect1.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright (c) 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 reflection; + +public class Reflect1 { + + public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException { + Class c = Class.forName("java.lang.Integer"); + Integer i = (Integer)c.newInstance(); + System.err.println(i); + } +} diff --git a/com.ibm.wala.core.testdata/src/slice/A.java b/com.ibm.wala.core.testdata/src/slice/A.java new file mode 100644 index 000000000..9c2211f9c --- /dev/null +++ b/com.ibm.wala.core.testdata/src/slice/A.java @@ -0,0 +1,19 @@ +package slice; + +class A { + + Object f; + Object g; + + Object foo() { + return new Integer(3); + } + + public Object getF() { + return f; + } + + public void setF(Object f) { + this.f = f; + } +} diff --git a/com.ibm.wala.core.testdata/src/slice/B.java b/com.ibm.wala.core.testdata/src/slice/B.java new file mode 100644 index 000000000..5aa1d852b --- /dev/null +++ b/com.ibm.wala.core.testdata/src/slice/B.java @@ -0,0 +1,7 @@ +package slice; + +class B extends A { + Object foo() { + return new Float(4); + } +} diff --git a/com.ibm.wala.core.testdata/src/slice/Slice1.java b/com.ibm.wala.core.testdata/src/slice/Slice1.java new file mode 100644 index 000000000..a70b6a99d --- /dev/null +++ b/com.ibm.wala.core.testdata/src/slice/Slice1.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * Copyright (c) 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 slice; + +public class Slice1 { + /** + * @param args + */ + public static void main(String[] args) { + int x = foo(1); + int y = bar(2); + System.out.println(x + y); + } + + static int foo(int x) { + return x + 2; + } + + static int bar(int x) { + return x + 3; + } + +} diff --git a/com.ibm.wala.core.testdata/src/slice/Slice2.java b/com.ibm.wala.core.testdata/src/slice/Slice2.java new file mode 100644 index 000000000..edf95b405 --- /dev/null +++ b/com.ibm.wala.core.testdata/src/slice/Slice2.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * Copyright (c) 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 slice; + +public class Slice2 { + /** + * @param args + */ + public static void main(String[] args) { + int x = foo(1); + int y = bar(2); + baz(x+y); + } + + public static void baz(int z) { + System.out.println(z); + } + + static int foo(int x) { + return x + 2; + } + + static int bar(int x) { + return x + 3; + } + +} diff --git a/com.ibm.wala.core.testdata/src/slice/Slice3.java b/com.ibm.wala.core.testdata/src/slice/Slice3.java new file mode 100644 index 000000000..52144c6bc --- /dev/null +++ b/com.ibm.wala.core.testdata/src/slice/Slice3.java @@ -0,0 +1,32 @@ +/******************************************************************************* + * Copyright (c) 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 slice; + +public class Slice3 { + static void doNothing(Object o) { + } + + /** + * @param args + */ + public static void main(String[] args) { + Object o1 = new Object(); + Object o2 = new Object(); + Object o3 = foo(o1, o2); + doNothing(o3); + } + + static Object foo(Object x, Object y) { + return x; + } + + +} diff --git a/com.ibm.wala.core.testdata/src/slice/Slice4.java b/com.ibm.wala.core.testdata/src/slice/Slice4.java new file mode 100644 index 000000000..3f0549e67 --- /dev/null +++ b/com.ibm.wala.core.testdata/src/slice/Slice4.java @@ -0,0 +1,30 @@ +/******************************************************************************* + * Copyright (c) 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 slice; + +public class Slice4 { + /** + * @param args + */ + public static void main(String[] args) { + int x = foo(1); + bar(x); + } + + static int foo(int x) { + return x + 2; + } + + static void bar(int x) { + return; + } + +} diff --git a/com.ibm.wala.core.testdata/src/slice/Slice5.java b/com.ibm.wala.core.testdata/src/slice/Slice5.java new file mode 100644 index 000000000..f9a536efd --- /dev/null +++ b/com.ibm.wala.core.testdata/src/slice/Slice5.java @@ -0,0 +1,33 @@ +/******************************************************************************* + * Copyright (c) 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 slice; + +public class Slice5 { + /** + * @param args + */ + public static void main(String[] args) { + int x = baz(); + bar(x); + } + + static int baz() { + return foo(1); + } + + static int foo(int x) { + return x + 2; + } + + static void bar(int x) { + return; + } +} diff --git a/com.ibm.wala.core.testdata/src/slice/TestArrays.java b/com.ibm.wala.core.testdata/src/slice/TestArrays.java new file mode 100644 index 000000000..5ee4c1aed --- /dev/null +++ b/com.ibm.wala.core.testdata/src/slice/TestArrays.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * Copyright (c) 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 slice; + +public class TestArrays { + + static void doNothing(Object o) {} + /** + * slice should include statements involving arr2 and i, + * exclude statements with arr1 and j + * @param args + */ + public static void main(String[] args) { + Object[] arr1 = new Object[10], arr2 = new Object[10]; + int i = 3; + int j = 4; + arr2[i] = new Object(); + arr1[j] = new Object(); + Object x = arr2[i]; + doNothing(x); + } + +} diff --git a/com.ibm.wala.core.testdata/src/slice/TestCD1.java b/com.ibm.wala.core.testdata/src/slice/TestCD1.java new file mode 100644 index 000000000..98e6dbc01 --- /dev/null +++ b/com.ibm.wala.core.testdata/src/slice/TestCD1.java @@ -0,0 +1,34 @@ +/******************************************************************************* + * Copyright (c) 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 slice; + +public class TestCD1 { + + static void doNothing(Object o) { + } + + /** + * + * @param args + */ + public static void main(String[] args) { + Integer I = (Integer) new A().foo(); + int i = I.intValue(); + if (i > 0) { + System.out.println("X"); + if (i > 1) { + System.out.println("Y"); + doNothing(I); + } + } + } + +} diff --git a/com.ibm.wala.core.testdata/src/slice/TestCD2.java b/com.ibm.wala.core.testdata/src/slice/TestCD2.java new file mode 100644 index 000000000..a74f8b070 --- /dev/null +++ b/com.ibm.wala.core.testdata/src/slice/TestCD2.java @@ -0,0 +1,34 @@ +/******************************************************************************* + * Copyright (c) 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 slice; + +public class TestCD2 { + + static void doNothing(Object o) { + } + + /** + * + * @param args + */ + public static void main(String[] args) { + Integer I = (Integer) new A().foo(); + int i = I.intValue(); + if (i > 0) { + System.out.println("X"); + doNothing(I); + if (i > 1) { + System.out.println("Y"); + } + } + } + +} diff --git a/com.ibm.wala.core.testdata/src/slice/TestCD3.java b/com.ibm.wala.core.testdata/src/slice/TestCD3.java new file mode 100644 index 000000000..95b834ba5 --- /dev/null +++ b/com.ibm.wala.core.testdata/src/slice/TestCD3.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright (c) 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 slice; + +public class TestCD3 { + + static void doNothing(Object o) { + } + + /** + * + * @param args + */ + public static void main(String[] args) { + Integer I = (Integer) new A().foo(); + int i = I.intValue(); + try { + if (i > 0) { + System.out.println("X"); + if (i > 1) { + System.out.println("Y"); + } + } + } catch (Throwable e) { + } + doNothing(I); + } +} diff --git a/com.ibm.wala.core.testdata/src/slice/TestFields.java b/com.ibm.wala.core.testdata/src/slice/TestFields.java new file mode 100644 index 000000000..72278212e --- /dev/null +++ b/com.ibm.wala.core.testdata/src/slice/TestFields.java @@ -0,0 +1,33 @@ +/******************************************************************************* + * Copyright (c) 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 slice; + +public class TestFields { + + private static void doNothing(Object o) {} + + /** + * slice should include a1 and o1, exclude + * a2 and o2 + * @param args + */ + public static void main(String[] args) { + Object o1 = new Object(); + Object o2 = new Object(); + A a1 = new A(); + A a2 = new A(); + a1.f = o1; + a2.f = o2; + Object o3 = a1.f; + doNothing(o3); + } + +} diff --git a/com.ibm.wala.core.testdata/src/slice/TestGlobal.java b/com.ibm.wala.core.testdata/src/slice/TestGlobal.java new file mode 100644 index 000000000..1b1c2698f --- /dev/null +++ b/com.ibm.wala.core.testdata/src/slice/TestGlobal.java @@ -0,0 +1,37 @@ +/******************************************************************************* + * Copyright (c) 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 slice; + +public class TestGlobal { + + static Object global1; + + static Object global2; + + static void copyGlobals() { + global2 = global1; + } + + static void doNothing(Object o) { + } + + /** + * make sure global variables are being properly handled + * @param args + */ + public static void main(String[] args) { + global1 = new Object(); + copyGlobals(); + Object x = global2; + doNothing(x); + } + +} diff --git a/com.ibm.wala.core.testdata/src/slice/TestId.java b/com.ibm.wala.core.testdata/src/slice/TestId.java new file mode 100644 index 000000000..a11cb1cda --- /dev/null +++ b/com.ibm.wala.core.testdata/src/slice/TestId.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * Copyright (c) 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 slice; + +public class TestId { + + static Object id(Object x) { + return x; + } + + static void doNothing(Object o) { + } + + /** + * check for context-sensitive handling of the identity function. + * o2 should be excluded + * + * @param args + */ + public static void main(String[] args) { + Object o1 = new Object(), o2 = new Object(); + Object o3 = id(o1); + id(o2); + doNothing(o3); + } + +} diff --git a/com.ibm.wala.core.testdata/src/slice/TestMultiTarget.java b/com.ibm.wala.core.testdata/src/slice/TestMultiTarget.java new file mode 100644 index 000000000..9b30cab06 --- /dev/null +++ b/com.ibm.wala.core.testdata/src/slice/TestMultiTarget.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * Copyright (c) 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 slice; + +public class TestMultiTarget { + + static void doNothing(Object o) { + } + + /** + * test a virtual call with multiple targets. slice should include statements + * assigning to a + * + * @param args + */ + public static void main(String[] args) { + A a = null; + if (args[0] == null) { + a = new A(); + } else { + a = new B(); + } + Object x = a.foo(); + doNothing(x); + } + +} diff --git a/com.ibm.wala.core.testdata/src/slice/TestPrimGetterSetter.java b/com.ibm.wala.core.testdata/src/slice/TestPrimGetterSetter.java new file mode 100644 index 000000000..92aa030dd --- /dev/null +++ b/com.ibm.wala.core.testdata/src/slice/TestPrimGetterSetter.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright (c) 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 slice; + +public class TestPrimGetterSetter { + + static class IntWrapper { + int i; + + int getI() { return i; } + + void setI(int i) { + this.i = i; + } + } + + public static void doNothing(int i) {} + /** + * @param args + */ + public static void main(String[] args) { + IntWrapper w = new IntWrapper(); + int x = 3; + w.setI(x); + int y = w.getI(); + doNothing(y); // slice on y + } +} diff --git a/com.ibm.wala.core.testdata/src/slice/TestRecursion.java b/com.ibm.wala.core.testdata/src/slice/TestRecursion.java new file mode 100644 index 000000000..658782d88 --- /dev/null +++ b/com.ibm.wala.core.testdata/src/slice/TestRecursion.java @@ -0,0 +1,40 @@ +/******************************************************************************* + * Copyright (c) 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 slice; + +public class TestRecursion { + + static Object find(A a, Object o) { + if (o == null) { + return a; + } else { + return find((A) a.f, o); + } + } + + static void doNothing(Object o) { + } + + /** + * test of recursion. Everything for a1, a2, and a3 should + * be included + * @param args + */ + public static void main(String[] args) { + A a1 = new A(), a2 = new A(), a3 = new A(); + a1.f = a2; + a2.f = a3; + Object x = find(a1, args[0]); + doNothing(x); + + } + +} diff --git a/com.ibm.wala.core.testdata/src/slice/TestThin1.java b/com.ibm.wala.core.testdata/src/slice/TestThin1.java new file mode 100644 index 000000000..24d2f648a --- /dev/null +++ b/com.ibm.wala.core.testdata/src/slice/TestThin1.java @@ -0,0 +1,32 @@ +/******************************************************************************* + * Copyright (c) 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 slice; + +public class TestThin1 { + + private static void doNothing(Object o) {} + + /** + * slice should not include any statements relating to + * base pointers + */ + public static void main(String[] args) { + Object o1 = new Object(); + A a1 = new A(); + A a2 = new A(); + a1.f = a2; + a2.g = o1; + A a3 = (A)a1.f; + Object o3 = a3.g; + doNothing(o3); + } + +} diff --git a/com.ibm.wala.core.tests/.classpath b/com.ibm.wala.core.tests/.classpath new file mode 100644 index 000000000..9f23b089a --- /dev/null +++ b/com.ibm.wala.core.tests/.classpath @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/com.ibm.wala.core.tests/.project b/com.ibm.wala.core.tests/.project new file mode 100644 index 000000000..479e43e10 --- /dev/null +++ b/com.ibm.wala.core.tests/.project @@ -0,0 +1,28 @@ + + + com.ibm.wala.core.tests + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/com.ibm.wala.core.tests/.settings/org.eclipse.jdt.core.prefs b/com.ibm.wala.core.tests/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 000000000..b3e6b9f72 --- /dev/null +++ b/com.ibm.wala.core.tests/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,62 @@ +#Fri Nov 17 09:37:12 EST 2006 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5 +org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve +org.eclipse.jdt.core.compiler.compliance=1.5 +org.eclipse.jdt.core.compiler.debug.lineNumber=generate +org.eclipse.jdt.core.compiler.debug.localVariable=generate +org.eclipse.jdt.core.compiler.debug.sourceFile=generate +org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.autoboxing=ignore +org.eclipse.jdt.core.compiler.problem.deprecation=warning +org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled +org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled +org.eclipse.jdt.core.compiler.problem.discouragedReference=warning +org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore +org.eclipse.jdt.core.compiler.problem.fieldHiding=ignore +org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning +org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning +org.eclipse.jdt.core.compiler.problem.forbiddenReference=error +org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning +org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning +org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=ignore +org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore +org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore +org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning +org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore +org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore +org.eclipse.jdt.core.compiler.problem.missingSerialVersion=ignore +org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning +org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning +org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore +org.eclipse.jdt.core.compiler.problem.nullReference=ignore +org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning +org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore +org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=ignore +org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning +org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled +org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning +org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled +org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore +org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning +org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning +org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore +org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning +org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore +org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=ignore +org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled +org.eclipse.jdt.core.compiler.problem.unusedImport=warning +org.eclipse.jdt.core.compiler.problem.unusedLabel=warning +org.eclipse.jdt.core.compiler.problem.unusedLocal=warning +org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore +org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled +org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled +org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning +org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning +org.eclipse.jdt.core.compiler.source=1.5 diff --git a/com.ibm.wala.core.tests/.settings/org.eclipse.jdt.ui.prefs b/com.ibm.wala.core.tests/.settings/org.eclipse.jdt.ui.prefs new file mode 100644 index 000000000..1cc660ac5 --- /dev/null +++ b/com.ibm.wala.core.tests/.settings/org.eclipse.jdt.ui.prefs @@ -0,0 +1,3 @@ +#Tue Oct 03 22:52:44 EDT 2006 +eclipse.preferences.version=1 +internal.default.compliance=default diff --git a/com.ibm.wala.core.tests/META-INF/MANIFEST.MF b/com.ibm.wala.core.tests/META-INF/MANIFEST.MF new file mode 100644 index 000000000..deccade58 --- /dev/null +++ b/com.ibm.wala.core.tests/META-INF/MANIFEST.MF @@ -0,0 +1,17 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: WALA Tests Plug-in +Bundle-SymbolicName: com.ibm.wala.core.tests +Bundle-Version: 1.0.0 +Bundle-Vendor: IBM +Bundle-Localization: plugin +Require-Bundle: com.ibm.wala.core, + org.junit, + org.eclipse.jface +Export-Package: com.ibm.wala.core.tests.basic, + com.ibm.wala.core.tests.callGraph, + com.ibm.wala.core.tests.cha, + com.ibm.wala.core.tests.ir, + com.ibm.wala.core.tests.util, + com.ibm.wala.examples.drivers, + com.ibm.wala.examples.properties diff --git a/com.ibm.wala.core.tests/build.properties b/com.ibm.wala.core.tests/build.properties new file mode 100644 index 000000000..c7886205e --- /dev/null +++ b/com.ibm.wala.core.tests/build.properties @@ -0,0 +1,5 @@ +source.. = src/,\ + dat/ +output.. = bin/ +bin.includes = META-INF/,\ + . diff --git a/com.ibm.wala.core.tests/build.xml b/com.ibm.wala.core.tests/build.xml new file mode 100644 index 000000000..d46ae7f13 --- /dev/null +++ b/com.ibm.wala.core.tests/build.xml @@ -0,0 +1,271 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/com.ibm.wala.core.tests/com.ibm.wala.core.tests/.classpath b/com.ibm.wala.core.tests/com.ibm.wala.core.tests/.classpath new file mode 100644 index 000000000..9f23b089a --- /dev/null +++ b/com.ibm.wala.core.tests/com.ibm.wala.core.tests/.classpath @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/com.ibm.wala.core.tests/com.ibm.wala.core.tests/.project b/com.ibm.wala.core.tests/com.ibm.wala.core.tests/.project new file mode 100644 index 000000000..479e43e10 --- /dev/null +++ b/com.ibm.wala.core.tests/com.ibm.wala.core.tests/.project @@ -0,0 +1,28 @@ + + + com.ibm.wala.core.tests + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/com.ibm.wala.core.tests/com.ibm.wala.core.tests/.settings/org.eclipse.jdt.core.prefs b/com.ibm.wala.core.tests/com.ibm.wala.core.tests/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 000000000..b3e6b9f72 --- /dev/null +++ b/com.ibm.wala.core.tests/com.ibm.wala.core.tests/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,62 @@ +#Fri Nov 17 09:37:12 EST 2006 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5 +org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve +org.eclipse.jdt.core.compiler.compliance=1.5 +org.eclipse.jdt.core.compiler.debug.lineNumber=generate +org.eclipse.jdt.core.compiler.debug.localVariable=generate +org.eclipse.jdt.core.compiler.debug.sourceFile=generate +org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.autoboxing=ignore +org.eclipse.jdt.core.compiler.problem.deprecation=warning +org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled +org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled +org.eclipse.jdt.core.compiler.problem.discouragedReference=warning +org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore +org.eclipse.jdt.core.compiler.problem.fieldHiding=ignore +org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning +org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning +org.eclipse.jdt.core.compiler.problem.forbiddenReference=error +org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning +org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning +org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=ignore +org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore +org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore +org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning +org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore +org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore +org.eclipse.jdt.core.compiler.problem.missingSerialVersion=ignore +org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning +org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning +org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore +org.eclipse.jdt.core.compiler.problem.nullReference=ignore +org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning +org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore +org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=ignore +org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning +org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled +org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning +org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled +org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore +org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning +org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning +org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore +org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning +org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore +org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=ignore +org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled +org.eclipse.jdt.core.compiler.problem.unusedImport=warning +org.eclipse.jdt.core.compiler.problem.unusedLabel=warning +org.eclipse.jdt.core.compiler.problem.unusedLocal=warning +org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore +org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled +org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled +org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning +org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning +org.eclipse.jdt.core.compiler.source=1.5 diff --git a/com.ibm.wala.core.tests/com.ibm.wala.core.tests/.settings/org.eclipse.jdt.ui.prefs b/com.ibm.wala.core.tests/com.ibm.wala.core.tests/.settings/org.eclipse.jdt.ui.prefs new file mode 100644 index 000000000..1cc660ac5 --- /dev/null +++ b/com.ibm.wala.core.tests/com.ibm.wala.core.tests/.settings/org.eclipse.jdt.ui.prefs @@ -0,0 +1,3 @@ +#Tue Oct 03 22:52:44 EDT 2006 +eclipse.preferences.version=1 +internal.default.compliance=default diff --git a/com.ibm.wala.core.tests/com.ibm.wala.core.tests/META-INF/MANIFEST.MF b/com.ibm.wala.core.tests/com.ibm.wala.core.tests/META-INF/MANIFEST.MF new file mode 100644 index 000000000..deccade58 --- /dev/null +++ b/com.ibm.wala.core.tests/com.ibm.wala.core.tests/META-INF/MANIFEST.MF @@ -0,0 +1,17 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: WALA Tests Plug-in +Bundle-SymbolicName: com.ibm.wala.core.tests +Bundle-Version: 1.0.0 +Bundle-Vendor: IBM +Bundle-Localization: plugin +Require-Bundle: com.ibm.wala.core, + org.junit, + org.eclipse.jface +Export-Package: com.ibm.wala.core.tests.basic, + com.ibm.wala.core.tests.callGraph, + com.ibm.wala.core.tests.cha, + com.ibm.wala.core.tests.ir, + com.ibm.wala.core.tests.util, + com.ibm.wala.examples.drivers, + com.ibm.wala.examples.properties diff --git a/com.ibm.wala.core.tests/com.ibm.wala.core.tests/build.properties b/com.ibm.wala.core.tests/com.ibm.wala.core.tests/build.properties new file mode 100644 index 000000000..c7886205e --- /dev/null +++ b/com.ibm.wala.core.tests/com.ibm.wala.core.tests/build.properties @@ -0,0 +1,5 @@ +source.. = src/,\ + dat/ +output.. = bin/ +bin.includes = META-INF/,\ + . diff --git a/com.ibm.wala.core.tests/com.ibm.wala.core.tests/build.xml b/com.ibm.wala.core.tests/com.ibm.wala.core.tests/build.xml new file mode 100644 index 000000000..d46ae7f13 --- /dev/null +++ b/com.ibm.wala.core.tests/com.ibm.wala.core.tests/build.xml @@ -0,0 +1,271 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/com.ibm.wala.core.tests/com.ibm.wala.core.tests/dat/GUIExclusions.xml b/com.ibm.wala.core.tests/com.ibm.wala.core.tests/dat/GUIExclusions.xml new file mode 100644 index 000000000..26c02a0a9 --- /dev/null +++ b/com.ibm.wala.core.tests/com.ibm.wala.core.tests/dat/GUIExclusions.xml @@ -0,0 +1,4 @@ + + + + diff --git a/com.ibm.wala.core.tests/com.ibm.wala.core.tests/dat/JLex.xml b/com.ibm.wala.core.tests/com.ibm.wala.core.tests/dat/JLex.xml new file mode 100644 index 000000000..7e578b02b --- /dev/null +++ b/com.ibm.wala.core.tests/com.ibm.wala.core.tests/dat/JLex.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/com.ibm.wala.core.tests/com.ibm.wala.core.tests/dat/bcel.xml b/com.ibm.wala.core.tests/com.ibm.wala.core.tests/dat/bcel.xml new file mode 100644 index 000000000..9201ec117 --- /dev/null +++ b/com.ibm.wala.core.tests/com.ibm.wala.core.tests/dat/bcel.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/com.ibm.wala.core.tests/com.ibm.wala.core.tests/dat/hello.xml b/com.ibm.wala.core.tests/com.ibm.wala.core.tests/dat/hello.xml new file mode 100644 index 000000000..5d6e0eccb --- /dev/null +++ b/com.ibm.wala.core.tests/com.ibm.wala.core.tests/dat/hello.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/com.ibm.wala.core.tests/com.ibm.wala.core.tests/dat/java_cup.xml b/com.ibm.wala.core.tests/com.ibm.wala.core.tests/dat/java_cup.xml new file mode 100644 index 000000000..0935a098f --- /dev/null +++ b/com.ibm.wala.core.tests/com.ibm.wala.core.tests/dat/java_cup.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/com.ibm.wala.core.tests/com.ibm.wala.core.tests/dat/wala.examples.properties.sample b/com.ibm.wala.core.tests/com.ibm.wala.core.tests/dat/wala.examples.properties.sample new file mode 100644 index 000000000..c48518f92 --- /dev/null +++ b/com.ibm.wala.core.tests/com.ibm.wala.core.tests/dat/wala.examples.properties.sample @@ -0,0 +1,30 @@ +############################################################################### +# WALA Examples property file +# This file defines the default settings for the WALA examples +############################################################################### + +################# Mandatory settings without default value #################### + +################### Mandatory settings with default value ###################### + + +############################ Optional settings ################################ + +### These are needed to run various individual examples + + +##### Ghostview executable +# Path to the ghostview executable +# For instance, on a windows OS it's typically something like C:/Progra~1/Ghostgum/gsview/gsview32.exe +# Default value: none +# Info: Must be absolute path +##### +#ghostview_exe = Your location + +##### DOT executable +# Path to the AT&T Graphview DOT executable +# For instance, on a windows OS it's typically something like C:/Progra~1/ATT/Graphviz/bin/dot.exe +# Default value: none +# Info: Must be absolute path +##### +#dot_exe = Your location diff --git a/com.ibm.wala.core.tests/com.ibm.wala.core.tests/dat/wala.testdata.xml b/com.ibm.wala.core.tests/com.ibm.wala.core.tests/dat/wala.testdata.xml new file mode 100644 index 000000000..e579cb64e --- /dev/null +++ b/com.ibm.wala.core.tests/com.ibm.wala.core.tests/dat/wala.testdata.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/com.ibm.wala.core.tests/com.ibm.wala.core.tests/javaCompiler...args b/com.ibm.wala.core.tests/com.ibm.wala.core.tests/javaCompiler...args new file mode 100644 index 000000000..c1f7e058e --- /dev/null +++ b/com.ibm.wala.core.tests/com.ibm.wala.core.tests/javaCompiler...args @@ -0,0 +1,42 @@ +#ADAPTER#ACCESS#com.ibm.wala.core/bin/[+com/ibm/wala/analysis/pointers/*;+com/ibm/wala/analysis/reflection/*;+com/ibm/wala/analysis/stackMachine/*;+com/ibm/wala/analysis/typeInference/*;+com/ibm/wala/cfg/*;+com/ibm/wala/cfg/cdg/*;+com/ibm/wala/classLoader/*;+com/ibm/wala/client/*;+com/ibm/wala/client/impl/*;+com/ibm/wala/core/plugin/*;+com/ibm/wala/dataflow/IFDS/*;+com/ibm/wala/dataflow/graph/*;+com/ibm/wala/dataflow/ssa/*;+com/ibm/wala/emf/wrappers/*;+com/ibm/wala/escape/*;+com/ibm/wala/fixedpoint/impl/*;+com/ibm/wala/fixpoint/*;+com/ibm/wala/ipa/callgraph/*;+com/ibm/wala/ipa/callgraph/impl/*;+com/ibm/wala/ipa/callgraph/propagation/*;+com/ibm/wala/ipa/callgraph/propagation/cfa/*;+com/ibm/wala/ipa/callgraph/propagation/rta/*;+com/ibm/wala/ipa/cfg/*;+com/ibm/wala/ipa/cha/*;+com/ibm/wala/ipa/summaries/*;+com/ibm/wala/model/*;+com/ibm/wala/model/java/lang/*;+com/ibm/wala/properties/*;+com/ibm/wala/ssa/*;+com/ibm/wala/ssa/analysis/*;+com/ibm/wala/types/*;+com/ibm/wala/util/*;+com/ibm/wala/util/bytecode/*;+com/ibm/wala/util/collections/*;+com/ibm/wala/util/config/*;+com/ibm/wala/util/debug/*;+com/ibm/wala/util/graph/*;+com/ibm/wala/util/graph/impl/*;+com/ibm/wala/util/graph/traverse/*;+com/ibm/wala/util/heapTrace/*;+com/ibm/wala/util/intertionalization/*;+com/ibm/wala/util/intset/*;+com/ibm/wala/util/io/*;+com/ibm/wala/util/logging/*;+com/ibm/wala/util/math/*;+com/ibm/wala/util/perf/*;+com/ibm/wala/util/properties/*;+com/ibm/wala/util/properties/impl/*;+com/ibm/wala/util/warnings/*;+com/ibm/wala/viz/*;?**/*] +#ADAPTER#ACCESS#com.ibm.wala.core/@dot[+com/ibm/wala/analysis/pointers/*;+com/ibm/wala/analysis/reflection/*;+com/ibm/wala/analysis/stackMachine/*;+com/ibm/wala/analysis/typeInference/*;+com/ibm/wala/cfg/*;+com/ibm/wala/cfg/cdg/*;+com/ibm/wala/classLoader/*;+com/ibm/wala/client/*;+com/ibm/wala/client/impl/*;+com/ibm/wala/core/plugin/*;+com/ibm/wala/dataflow/IFDS/*;+com/ibm/wala/dataflow/graph/*;+com/ibm/wala/dataflow/ssa/*;+com/ibm/wala/emf/wrappers/*;+com/ibm/wala/escape/*;+com/ibm/wala/fixedpoint/impl/*;+com/ibm/wala/fixpoint/*;+com/ibm/wala/ipa/callgraph/*;+com/ibm/wala/ipa/callgraph/impl/*;+com/ibm/wala/ipa/callgraph/propagation/*;+com/ibm/wala/ipa/callgraph/propagation/cfa/*;+com/ibm/wala/ipa/callgraph/propagation/rta/*;+com/ibm/wala/ipa/cfg/*;+com/ibm/wala/ipa/cha/*;+com/ibm/wala/ipa/summaries/*;+com/ibm/wala/model/*;+com/ibm/wala/model/java/lang/*;+com/ibm/wala/properties/*;+com/ibm/wala/ssa/*;+com/ibm/wala/ssa/analysis/*;+com/ibm/wala/types/*;+com/ibm/wala/util/*;+com/ibm/wala/util/bytecode/*;+com/ibm/wala/util/collections/*;+com/ibm/wala/util/config/*;+com/ibm/wala/util/debug/*;+com/ibm/wala/util/graph/*;+com/ibm/wala/util/graph/impl/*;+com/ibm/wala/util/graph/traverse/*;+com/ibm/wala/util/heapTrace/*;+com/ibm/wala/util/intertionalization/*;+com/ibm/wala/util/intset/*;+com/ibm/wala/util/io/*;+com/ibm/wala/util/logging/*;+com/ibm/wala/util/math/*;+com/ibm/wala/util/perf/*;+com/ibm/wala/util/properties/*;+com/ibm/wala/util/properties/impl/*;+com/ibm/wala/util/warnings/*;+com/ibm/wala/viz/*;?**/*] +#ADAPTER#ACCESS#com.ibm.wala.emf/bin/[+com/ibm/wala/ecore/common/*;+com/ibm/wala/ecore/common/impl/*;+com/ibm/wala/ecore/common/util/*;+com/ibm/wala/ecore/graph/*;+com/ibm/wala/ecore/graph/impl/*;+com/ibm/wala/ecore/graph/util/*;+com/ibm/wala/ecore/j2ee/scope/*;+com/ibm/wala/ecore/j2ee/scope/impl/*;+com/ibm/wala/ecore/j2ee/scope/util/*;+com/ibm/wala/ecore/java/*;+com/ibm/wala/ecore/java/callGraph/*;+com/ibm/wala/ecore/java/callGraph/impl/*;+com/ibm/wala/ecore/java/callGraph/util/*;+com/ibm/wala/ecore/java/impl/*;+com/ibm/wala/ecore/java/pointerAnalysis/*;+com/ibm/wala/ecore/java/pointerAnalysis/impl/*;+com/ibm/wala/ecore/java/pointerAnalysis/util/*;+com/ibm/wala/ecore/java/scope/*;+com/ibm/wala/ecore/java/scope/impl/*;+com/ibm/wala/ecore/java/scope/util/*;+com/ibm/wala/ecore/java/util/*;+com/ibm/wala/ecore/perf/*;+com/ibm/wala/ecore/perf/impl/*;+com/ibm/wala/ecore/perf/util/*;+com/ibm/wala/ecore/regex/*;+com/ibm/wala/ecore/regex/impl/*;+com/ibm/wala/ecore/regex/util/*;?**/*] +#ADAPTER#ACCESS#com.ibm.wala.emf/@dot[+com/ibm/wala/ecore/common/*;+com/ibm/wala/ecore/common/impl/*;+com/ibm/wala/ecore/common/util/*;+com/ibm/wala/ecore/graph/*;+com/ibm/wala/ecore/graph/impl/*;+com/ibm/wala/ecore/graph/util/*;+com/ibm/wala/ecore/j2ee/scope/*;+com/ibm/wala/ecore/j2ee/scope/impl/*;+com/ibm/wala/ecore/j2ee/scope/util/*;+com/ibm/wala/ecore/java/*;+com/ibm/wala/ecore/java/callGraph/*;+com/ibm/wala/ecore/java/callGraph/impl/*;+com/ibm/wala/ecore/java/callGraph/util/*;+com/ibm/wala/ecore/java/impl/*;+com/ibm/wala/ecore/java/pointerAnalysis/*;+com/ibm/wala/ecore/java/pointerAnalysis/impl/*;+com/ibm/wala/ecore/java/pointerAnalysis/util/*;+com/ibm/wala/ecore/java/scope/*;+com/ibm/wala/ecore/java/scope/impl/*;+com/ibm/wala/ecore/java/scope/util/*;+com/ibm/wala/ecore/java/util/*;+com/ibm/wala/ecore/perf/*;+com/ibm/wala/ecore/perf/impl/*;+com/ibm/wala/ecore/perf/util/*;+com/ibm/wala/ecore/regex/*;+com/ibm/wala/ecore/regex/impl/*;+com/ibm/wala/ecore/regex/util/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.core.runtime_3.2.0.v20060603.jar[~org/eclipse/core/internal/preferences/legacy/*;~org/eclipse/core/internal/runtime/*;+org/eclipse/core/runtime/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.osgi_3.2.0.v20060601.jar[+org/eclipse/osgi/event/*;+org/eclipse/osgi/framework/console/*;+org/eclipse/osgi/framework/eventmgr/*;+org/eclipse/osgi/framework/log/*;+org/eclipse/osgi/service/datalocation/*;+org/eclipse/osgi/service/debug/*;+org/eclipse/osgi/service/environment/*;+org/eclipse/osgi/service/localization/*;+org/eclipse/osgi/service/pluginconversion/*;+org/eclipse/osgi/service/resolver/*;+org/eclipse/osgi/service/runnable/*;+org/eclipse/osgi/service/urlconversion/*;+org/eclipse/osgi/storagemanager/*;+org/eclipse/osgi/util/*;+org/osgi/framework/*;+org/osgi/service/condpermadmin/*;+org/osgi/service/packageadmin/*;+org/osgi/service/permissionadmin/*;+org/osgi/service/startlevel/*;+org/osgi/service/url/*;+org/osgi/util/tracker/*;~org/eclipse/core/runtime/adaptor/*;~org/eclipse/core/runtime/internal/adaptor/*;~org/eclipse/core/runtime/internal/stats/*;~org/eclipse/osgi/baseadaptor/*;~org/eclipse/osgi/baseadaptor/bundlefile/*;~org/eclipse/osgi/baseadaptor/hooks/*;~org/eclipse/osgi/baseadaptor/loader/*;~org/eclipse/osgi/framework/adaptor/*;~org/eclipse/osgi/framework/debug/*;~org/eclipse/osgi/framework/internal/core/*;~org/eclipse/osgi/framework/internal/protocol/*;~org/eclipse/osgi/framework/internal/protocol/bundleentry/*;~org/eclipse/osgi/framework/internal/protocol/bundleresource/*;~org/eclipse/osgi/framework/internal/protocol/reference/*;~org/eclipse/osgi/framework/internal/reliablefile/*;~org/eclipse/osgi/framework/launcher/*;~org/eclipse/osgi/framework/util/*;~org/eclipse/osgi/internal/baseadaptor/*;~org/eclipse/osgi/internal/module/*;~org/eclipse/osgi/internal/profile/*;~org/eclipse/osgi/internal/resolver/*;~org/eclipse/osgi/internal/verifier/*;~org/eclipse/osgi/internal/provisional/verifier/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.equinox.common_3.2.0.v20060603.jar[~org/eclipse/core/internal/runtime/*;~org/eclipse/core/internal/boot/*;+org/eclipse/core/runtime/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.core.jobs_3.2.0.v20060603.jar[~org/eclipse/core/internal/jobs/*;+org/eclipse/core/runtime/jobs/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.core.runtime.compatibility.registry_3.2.0.v20060603/runtime_registry_compatibility.jar[~org/eclipse/core/internal/registry/*;~org/eclipse/core/internal/registry/osgi/*;~org/eclipse/core/internal/registry/spi/*;+org/eclipse/core/runtime/*;+org/eclipse/core/runtime/dynamichelpers/*;+org/eclipse/core/runtime/spi/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.core.runtime.compatibility.registry_3.2.0.v20060603[~org/eclipse/core/internal/registry/*;~org/eclipse/core/internal/registry/osgi/*;~org/eclipse/core/internal/registry/spi/*;+org/eclipse/core/runtime/*;+org/eclipse/core/runtime/dynamichelpers/*;+org/eclipse/core/runtime/spi/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.equinox.registry_3.2.0.v20060601.jar[~org/eclipse/core/internal/registry/*;~org/eclipse/core/internal/registry/osgi/*;~org/eclipse/core/internal/registry/spi/*;+org/eclipse/core/runtime/*;+org/eclipse/core/runtime/dynamichelpers/*;+org/eclipse/core/runtime/spi/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.apache.xerces_2.8.0.v200606131651/resolver.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.apache.xerces_2.8.0.v200606131651/xercesImpl.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.apache.xerces_2.8.0.v200606131651/xml-apis.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.equinox.preferences_3.2.0.v20060601.jar[~org/eclipse/core/internal/preferences/*;~org/eclipse/core/internal/preferences/exchange/*;+org/eclipse/core/runtime/preferences/*;+org/osgi/service/prefs/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.core.runtime.compatibility.registry_3.2.0.v20060603/@dot[~org/eclipse/core/internal/registry/*;~org/eclipse/core/internal/registry/osgi/*;~org/eclipse/core/internal/registry/spi/*;+org/eclipse/core/runtime/*;+org/eclipse/core/runtime/dynamichelpers/*;+org/eclipse/core/runtime/spi/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.core.contenttype_3.2.0.v20060603.jar[~org/eclipse/core/internal/content/*;+org/eclipse/core/runtime/content/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.core.runtime.compatibility.auth_3.2.0.v20060601.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.emf.ecore_2.2.0.v200606271057.jar[+org/eclipse/emf/ecore/*;+org/eclipse/emf/ecore/impl/*;+org/eclipse/emf/ecore/plugin/*;+org/eclipse/emf/ecore/resource/*;+org/eclipse/emf/ecore/resource/impl/*;+org/eclipse/emf/ecore/util/*;+org/eclipse/emf/ecore/xml/namespace/*;+org/eclipse/emf/ecore/xml/namespace/impl/*;+org/eclipse/emf/ecore/xml/namespace/util/*;+org/eclipse/emf/ecore/xml/type/*;+org/eclipse/emf/ecore/xml/type/impl/*;+org/eclipse/emf/ecore/xml/type/internal/*;+org/eclipse/emf/ecore/xml/type/util/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.emf.common_2.2.0.v200606271057.jar[+org/eclipse/emf/common/*;+org/eclipse/emf/common/archive/*;+org/eclipse/emf/common/command/*;+org/eclipse/emf/common/notify/*;+org/eclipse/emf/common/notify/impl/*;+org/eclipse/emf/common/util/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.core.resources_3.2.0.v20060603.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.core.resources.compatibility_3.2.0.v20060603.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.core.resources.win32_3.2.0.v20060603.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.core.runtime.compatibility_3.1.100.v20060603.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.update.configurator_3.2.0.v20060605.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.ant.core_3.1.100.v20060531.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.core.variables_3.1.100.v20060605.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.core.expressions_3.2.0.v20060605-1400.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.core.filesystem_1.0.0.v20060603.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.core.filesystem.win32.x86_1.0.0.v20060603.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.emf.ecore.xmi_2.2.0.v200606271057.jar[+org/eclipse/emf/ecore/xmi/*;+org/eclipse/emf/ecore/xmi/impl/*;+org/eclipse/emf/ecore/xmi/util/*;?**/*] +#ADAPTER#ACCESS#com.ibm.wala.shrike/bin/[+com/ibm/wala/shrike/bench/*;+com/ibm/wala/shrike/copywriter/*;+com/ibm/wala/shrike/tools/*;+com/ibm/wala/shrikeBT/*;+com/ibm/wala/shrikeBT/analysis/*;+com/ibm/wala/shrikeBT/info/*;+com/ibm/wala/shrikeBT/shrikeCT/*;+com/ibm/wala/shrikeBT/shrikeCT/tools/*;+com/ibm/wala/shrikeBT/tools/*;+com/ibm/wala/shrikeCT/*;?**/*] +#ADAPTER#ACCESS#com.ibm.wala.shrike/@dot[+com/ibm/wala/shrike/bench/*;+com/ibm/wala/shrike/copywriter/*;+com/ibm/wala/shrike/tools/*;+com/ibm/wala/shrikeBT/*;+com/ibm/wala/shrikeBT/analysis/*;+com/ibm/wala/shrikeBT/info/*;+com/ibm/wala/shrikeBT/shrikeCT/*;+com/ibm/wala/shrikeBT/shrikeCT/tools/*;+com/ibm/wala/shrikeBT/tools/*;+com/ibm/wala/shrikeCT/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.jface_3.2.0.I20060605-1400.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.swt_3.2.0.v3232o.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.swt.win32.win32.x86_3.2.0.v3232m.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.core.commands_3.2.0.I20060605-1400.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.jdt.core_3.2.0.v_671.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.text_3.2.0.v20060605-1400.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/com.ibm.icu_3.4.4.1.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.team.core_3.2.0.I200606051140.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.junit_3.8.1/junit.jar[+junit/awtui/*;+junit/extensions/*;+junit/framework/*;+junit/runner/*;+junit/swingui/*;+junit/swingui/icons/*;+junit/textui/*;?**/*] diff --git a/com.ibm.wala.core.tests/com.ibm.wala.core.tests/launchers/ExportCallGraphToXML.launch b/com.ibm.wala.core.tests/com.ibm.wala.core.tests/launchers/ExportCallGraphToXML.launch new file mode 100644 index 000000000..5abbcec37 --- /dev/null +++ b/com.ibm.wala.core.tests/com.ibm.wala.core.tests/launchers/ExportCallGraphToXML.launch @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/com.ibm.wala.core.tests/com.ibm.wala.core.tests/launchers/ExportTypeHierarchyToXML.launch b/com.ibm.wala.core.tests/com.ibm.wala.core.tests/launchers/ExportTypeHierarchyToXML.launch new file mode 100644 index 000000000..e272ce68a --- /dev/null +++ b/com.ibm.wala.core.tests/com.ibm.wala.core.tests/launchers/ExportTypeHierarchyToXML.launch @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/com.ibm.wala.core.tests/com.ibm.wala.core.tests/launchers/GVCallGraph.launch b/com.ibm.wala.core.tests/com.ibm.wala.core.tests/launchers/GVCallGraph.launch new file mode 100644 index 000000000..0f56985de --- /dev/null +++ b/com.ibm.wala.core.tests/com.ibm.wala.core.tests/launchers/GVCallGraph.launch @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/com.ibm.wala.core.tests/com.ibm.wala.core.tests/launchers/GVControlDependenceGraph.launch b/com.ibm.wala.core.tests/com.ibm.wala.core.tests/launchers/GVControlDependenceGraph.launch new file mode 100644 index 000000000..de8197e8d --- /dev/null +++ b/com.ibm.wala.core.tests/com.ibm.wala.core.tests/launchers/GVControlDependenceGraph.launch @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/com.ibm.wala.core.tests/com.ibm.wala.core.tests/launchers/GVSDG.launch b/com.ibm.wala.core.tests/com.ibm.wala.core.tests/launchers/GVSDG.launch new file mode 100644 index 000000000..c361a3962 --- /dev/null +++ b/com.ibm.wala.core.tests/com.ibm.wala.core.tests/launchers/GVSDG.launch @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/com.ibm.wala.core.tests/com.ibm.wala.core.tests/launchers/GVSlice.launch b/com.ibm.wala.core.tests/com.ibm.wala.core.tests/launchers/GVSlice.launch new file mode 100644 index 000000000..d059c9c67 --- /dev/null +++ b/com.ibm.wala.core.tests/com.ibm.wala.core.tests/launchers/GVSlice.launch @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/com.ibm.wala.core.tests/com.ibm.wala.core.tests/launchers/GVTypeHierarchy.launch b/com.ibm.wala.core.tests/com.ibm.wala.core.tests/launchers/GVTypeHierarchy.launch new file mode 100644 index 000000000..860864583 --- /dev/null +++ b/com.ibm.wala.core.tests/com.ibm.wala.core.tests/launchers/GVTypeHierarchy.launch @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/com.ibm.wala.core.tests/com.ibm.wala.core.tests/launchers/GVWalaIR.launch b/com.ibm.wala.core.tests/com.ibm.wala.core.tests/launchers/GVWalaIR.launch new file mode 100644 index 000000000..1b04da957 --- /dev/null +++ b/com.ibm.wala.core.tests/com.ibm.wala.core.tests/launchers/GVWalaIR.launch @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/com.ibm.wala.core.tests/com.ibm.wala.core.tests/launchers/GetEnv.launch b/com.ibm.wala.core.tests/com.ibm.wala.core.tests/launchers/GetEnv.launch new file mode 100644 index 000000000..ea2696a61 --- /dev/null +++ b/com.ibm.wala.core.tests/com.ibm.wala.core.tests/launchers/GetEnv.launch @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/com.ibm.wala.core.tests/com.ibm.wala.core.tests/launchers/SWTCallGraph.launch b/com.ibm.wala.core.tests/com.ibm.wala.core.tests/launchers/SWTCallGraph.launch new file mode 100644 index 000000000..daac4b660 --- /dev/null +++ b/com.ibm.wala.core.tests/com.ibm.wala.core.tests/launchers/SWTCallGraph.launch @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/com.ibm.wala.core.tests/com.ibm.wala.core.tests/launchers/SWTPointsTo.launch b/com.ibm.wala.core.tests/com.ibm.wala.core.tests/launchers/SWTPointsTo.launch new file mode 100644 index 000000000..5b6675f32 --- /dev/null +++ b/com.ibm.wala.core.tests/com.ibm.wala.core.tests/launchers/SWTPointsTo.launch @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/com.ibm.wala.core.tests/com.ibm.wala.core.tests/launchers/SWTTypeHierarchy.launch b/com.ibm.wala.core.tests/com.ibm.wala.core.tests/launchers/SWTTypeHierarchy.launch new file mode 100644 index 000000000..f2a2fd62b --- /dev/null +++ b/com.ibm.wala.core.tests/com.ibm.wala.core.tests/launchers/SWTTypeHierarchy.launch @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/com.ibm.wala.core.tests/com.ibm.wala.core.tests/launchers/SimpleThreadEscapeAnalysis.launch b/com.ibm.wala.core.tests/com.ibm.wala.core.tests/launchers/SimpleThreadEscapeAnalysis.launch new file mode 100644 index 000000000..08d5bb91c --- /dev/null +++ b/com.ibm.wala.core.tests/com.ibm.wala.core.tests/launchers/SimpleThreadEscapeAnalysis.launch @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/com.ibm.wala.core.tests/com.ibm.wala.core.tests/launchers/SlicerTest.launch b/com.ibm.wala.core.tests/com.ibm.wala.core.tests/launchers/SlicerTest.launch new file mode 100644 index 000000000..fb0df2962 --- /dev/null +++ b/com.ibm.wala.core.tests/com.ibm.wala.core.tests/launchers/SlicerTest.launch @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/com.ibm.wala.core.tests/com.ibm.wala.core.tests/launchers/wala.core short profile.launch b/com.ibm.wala.core.tests/com.ibm.wala.core.tests/launchers/wala.core short profile.launch new file mode 100644 index 000000000..c1a77a6f1 --- /dev/null +++ b/com.ibm.wala.core.tests/com.ibm.wala.core.tests/launchers/wala.core short profile.launch @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/com.ibm.wala.core.tests/com.ibm.wala.core.tests/launchers/wala.core.launch b/com.ibm.wala.core.tests/com.ibm.wala.core.tests/launchers/wala.core.launch new file mode 100644 index 000000000..4214916d0 --- /dev/null +++ b/com.ibm.wala.core.tests/com.ibm.wala.core.tests/launchers/wala.core.launch @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/com.ibm.wala.core.tests/com.ibm.wala.core.tests/src/com/ibm/wala/core/tests/basic/GraphDataflowTest.java b/com.ibm.wala.core.tests/com.ibm.wala.core.tests/src/com/ibm/wala/core/tests/basic/GraphDataflowTest.java new file mode 100644 index 000000000..e37aecd75 --- /dev/null +++ b/com.ibm.wala.core.tests/com.ibm.wala.core.tests/src/com/ibm/wala/core/tests/basic/GraphDataflowTest.java @@ -0,0 +1,214 @@ +/******************************************************************************* + * 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.core.tests.basic; + +import com.ibm.wala.core.tests.util.WalaTestCase; +import com.ibm.wala.dataflow.graph.AbstractMeetOperator; +import com.ibm.wala.dataflow.graph.BitVectorFilter; +import com.ibm.wala.dataflow.graph.BitVectorFramework; +import com.ibm.wala.dataflow.graph.BitVectorIdentity; +import com.ibm.wala.dataflow.graph.BitVectorSolver; +import com.ibm.wala.dataflow.graph.BitVectorUnion; +import com.ibm.wala.dataflow.graph.BitVectorUnionConstant; +import com.ibm.wala.dataflow.graph.DataflowSolver; +import com.ibm.wala.dataflow.graph.ITransferFunctionProvider; +import com.ibm.wala.fixedpoint.impl.UnaryOperator; +import com.ibm.wala.fixpoint.BitVectorVariable; +import com.ibm.wala.util.debug.Assertions; +import com.ibm.wala.util.graph.Graph; +import com.ibm.wala.util.graph.impl.SlowSparseNumberedGraph; +import com.ibm.wala.util.intset.BitVector; +import com.ibm.wala.util.intset.MutableMapping; +import com.ibm.wala.util.intset.OrdinalSetMapping; + +/** + * + * Simple Regression test for a graph-based dataflow problem + * + * @author Donald P Pazel + * @author sfink + * @author Julian Dolby (dolby@us.ibm.com) + */ +public class GraphDataflowTest extends WalaTestCase { + + public static final String nodeNames = "ABCDEFGH"; + protected final static String[] nodes = new String[nodeNames.length()]; + + public GraphDataflowTest() { + super("GraphDataflowTest"); + } + + /** + * A simple test of the GraphBitVectorDataflow system + */ + public void testSolverNodeEdge() { + Graph G = buildGraph(); + String result = solveNodeEdge(G); + System.err.println(result); + if (!result.equals(expectedStringNodeEdge())) { + System.err.println("Uh oh."); + System.err.println(expectedStringNodeEdge()); + } + assertEquals(expectedStringNodeEdge(), result); + } + + public void testSolverNodeOnly() { + Graph G = buildGraph(); + String result = solveNodeOnly(G); + System.err.println(result); + assertEquals(expectedStringNodeOnly(), result); + } + + /** + * @return the expected dataflow result as a String + */ + public static String expectedStringNodeOnly() { + StringBuffer result = new StringBuffer("------\n"); + result.append("Node A(0) = { 0 }\n"); + result.append("Node B(1) = { 0 1 }\n"); + result.append("Node C(2) = { 0 1 2 }\n"); + result.append("Node D(3) = { 0 1 3 }\n"); + result.append("Node E(4) = { 0 1 2 3 4 }\n"); + result.append("Node F(5) = { 0 1 2 3 4 5 }\n"); + result.append("Node G(6) = { 6 }\n"); + result.append("Node H(7) = { 7 }\n"); + return result.toString(); + } + + public static String expectedStringNodeEdge() { + StringBuffer result = new StringBuffer("------\n"); + result.append("Node A(0) = { 0 }\n"); + result.append("Node B(1) = { 0 1 }\n"); + result.append("Node C(2) = { 0 2 }\n"); + result.append("Node D(3) = { 1 3 }\n"); + result.append("Node E(4) = { 0 1 2 3 4 }\n"); + result.append("Node F(5) = { 0 1 2 3 4 5 }\n"); + result.append("Node G(6) = { 6 }\n"); + result.append("Node H(7) = { 7 }\n"); + return result.toString(); + } + + /** + * @return a graph with the expected structure + */ + private static Graph buildGraph() { + Graph G = new SlowSparseNumberedGraph(); + for (int i = 0; i < nodeNames.length(); i++) { + String n = nodeNames.substring(i, i + 1); + G.addNode(n); + nodes[i] = n; + } + G.addEdge(nodes[0], nodes[1]); + G.addEdge(nodes[1], nodes[2]); + G.addEdge(nodes[1], nodes[3]); + G.addEdge(nodes[2], nodes[4]); + G.addEdge(nodes[3], nodes[4]); + G.addEdge(nodes[4], nodes[5]); + return G; + } + + /** + * Solve the dataflow system and return the result as a string + */ + private String solveNodeOnly(Graph G) { + final OrdinalSetMapping values = new MutableMapping(nodes); + ITransferFunctionProvider functions = new ITransferFunctionProvider() { + + public UnaryOperator getNodeTransferFunction(String node) { + return new BitVectorUnionConstant(values.getMappedIndex(node)); + } + + public boolean hasNodeTransferFunctions() { + return true; + } + + public UnaryOperator getEdgeTransferFunction(String from, String to) { + Assertions.UNREACHABLE(); + return null; + } + + public boolean hasEdgeTransferFunctions() { + return false; + } + + public AbstractMeetOperator getMeetOperator() { + return BitVectorUnion.instance(); + } + + }; + + BitVectorFramework F = new BitVectorFramework(G, functions, values); + DataflowSolver s = new BitVectorSolver(F); + s.solve(); + return result2String(s); + } + + private String solveNodeEdge(Graph G) { + final OrdinalSetMapping values = new MutableMapping(nodes); + ITransferFunctionProvider functions = new ITransferFunctionProvider() { + + public UnaryOperator getNodeTransferFunction(String node) { + return new BitVectorUnionConstant(values.getMappedIndex(node)); + } + + public boolean hasNodeTransferFunctions() { + return true; + } + + private BitVector zero() { + BitVector b = new BitVector(); + b.set(0); + return b; + } + + private BitVector one() { + BitVector b = new BitVector(); + b.set(1); + return b; + } + + public UnaryOperator getEdgeTransferFunction(String from, String to) { + if (from == nodes[1] && to == nodes[3]) + return new BitVectorFilter(zero()); + else if (from == nodes[1] && to == nodes[2]) + return new BitVectorFilter(one()); + else { + return BitVectorIdentity.instance(); + } + } + + public boolean hasEdgeTransferFunctions() { + return true; + } + + public AbstractMeetOperator getMeetOperator() { + return BitVectorUnion.instance(); + } + + }; + + BitVectorFramework F = new BitVectorFramework(G, functions, values); + DataflowSolver s = new BitVectorSolver(F); + s.solve(); + return result2String(s); + } + + public static String result2String(DataflowSolver solver) { + StringBuffer result = new StringBuffer("------\n"); + for (int i = 0; i < nodes.length; i++) { + String n = nodes[i]; + BitVectorVariable varI = (BitVectorVariable) solver.getOut(n); + String s = varI.toString(); + result.append("Node " + n + "(" + i + ") = " + s + "\n"); + } + return result.toString(); + } +} \ No newline at end of file diff --git a/com.ibm.wala.core.tests/com.ibm.wala.core.tests/src/com/ibm/wala/core/tests/basic/PrimitivesTest.java b/com.ibm.wala.core.tests/com.ibm.wala.core.tests/src/com/ibm/wala/core/tests/basic/PrimitivesTest.java new file mode 100644 index 000000000..3dbe937d4 --- /dev/null +++ b/com.ibm.wala.core.tests/com.ibm.wala.core.tests/src/com/ibm/wala/core/tests/basic/PrimitivesTest.java @@ -0,0 +1,585 @@ +/******************************************************************************* + * 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.core.tests.basic; + +import java.util.Collection; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import com.ibm.wala.core.tests.util.WalaTestCase; +import com.ibm.wala.util.collections.BimodalMap; +import com.ibm.wala.util.collections.Iterator2Collection; +import com.ibm.wala.util.collections.SmallMap; +import com.ibm.wala.util.graph.Dominators; +import com.ibm.wala.util.graph.Graph; +import com.ibm.wala.util.graph.NumberedGraph; +import com.ibm.wala.util.graph.impl.SlowSparseNumberedGraph; +import com.ibm.wala.util.graph.traverse.BFSPathFinder; +import com.ibm.wala.util.graph.traverse.BoundedBFSIterator; +import com.ibm.wala.util.intset.BasicNonNegativeIntRelation; +import com.ibm.wala.util.intset.BimodalMutableIntSetFactory; +import com.ibm.wala.util.intset.BitVector; +import com.ibm.wala.util.intset.BitVectorIntSetFactory; +import com.ibm.wala.util.intset.IBinaryNonNegativeIntRelation; +import com.ibm.wala.util.intset.IntPair; +import com.ibm.wala.util.intset.IntSet; +import com.ibm.wala.util.intset.IntSetUtil; +import com.ibm.wala.util.intset.IntegerUnionFind; +import com.ibm.wala.util.intset.MutableIntSet; +import com.ibm.wala.util.intset.MutableIntSetFactory; +import com.ibm.wala.util.intset.MutableSharedBitVectorIntSetFactory; +import com.ibm.wala.util.intset.MutableSparseIntSetFactory; +import com.ibm.wala.util.intset.SparseIntSet; + +/** + * + * JUnit tests for some primitive operations. + * + * @author sfink + */ +public class PrimitivesTest extends WalaTestCase { + + /** + * + */ + public PrimitivesTest() { + super("PrimitivesTest"); + } + + /** + * @param arg0 + */ + public PrimitivesTest(String arg0) { + super(arg0); + } + + /** + * Test the MutableSparseIntSet implementation + */ + private void doMutableIntSet(MutableIntSetFactory factory) { + MutableIntSet v = factory.parse("{9,17}"); + MutableIntSet w = factory.make(new int[] {}); + MutableIntSet x = factory.make(new int[] { 7, 4, 2, 4, 2, 2 }); + MutableIntSet y = factory.make(new int[] { 7, 7, 7, 2, 7, 1 }); + MutableIntSet z = factory.parse("{ 9 }"); + + System.out.println(w); // { } + System.out.println(x); // { 2 4 7 } + System.out.println(y); // { 1 2 7 } + System.out.println(z); // { 9 } + + MutableIntSet temp = factory.makeCopy(x); + temp.intersectWith(y); + System.out.println(temp); // { 2 7 } + temp.copySet(x); + temp.addAll(y); + System.out.println(temp); // { 1 2 4 7 } + temp.copySet(x); + System.out.println(IntSetUtil.diff(x, y, factory)); // { 4 } + System.out.println(IntSetUtil.diff(v, z, factory)); // { 17 } + System.out.println(IntSetUtil.diff(z, v, factory)); // { } + + // assertTrue(x.union(z).intersection(y.union(z)).equals(x.intersection(y).union(z))); + MutableIntSet temp1 = factory.makeCopy(x); + MutableIntSet temp2 = factory.makeCopy(x); + MutableIntSet tempY = factory.makeCopy(y); + temp1.addAll(z); + tempY.addAll(z); + temp1.intersectWith(tempY); + temp2.intersectWith(y); + temp2.addAll(z); + assertTrue(temp1.sameValue(temp2)); + + // assertTrue(x.union(z).diff(z).equals(x)); + assertTrue(w.isEmpty()); + assertTrue(IntSetUtil.diff(x, x, factory).isEmpty()); + assertTrue(IntSetUtil.diff(z, v, factory).isEmpty()); + assertTrue(IntSetUtil.diff(v, z, factory).sameValue(SparseIntSet.singleton(17))); + assertTrue(IntSetUtil.diff(z, v, factory).isEmpty()); + assertTrue(z.isSubset(v)); + temp = factory.make(); + temp.add(4); + System.out.println(temp); // { 4 } + temp.add(7); + System.out.println(temp); // { 4 7 } + temp.add(2); + System.out.println(temp); // { 2 4 7 } + System.out.println(x); // { 2 4 7 } + assertTrue(temp.sameValue(x)); + + MutableIntSet a = factory.parse("{1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31,33,35,37,39,41,43,45,47,49,51,53,55,57,59}"); + System.out.println(a); // { 1 3 5 7 9 11 13 15 17 19 21 23 25 27 29 31 33 + // 35 + // 37 39 41 43 45 47 49 51 53 55 57 59 } + assertTrue(a.sameValue(a)); + IntSet i = a.intersection(temp); + assertTrue(i.sameValue(SparseIntSet.singleton(7))); + a.add(100); + assertTrue(a.sameValue(a)); + + MutableIntSet b = factory.parse("{1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31,33,35,37,39,41,43,45,47,49,51,53,55,57,59,100}"); + assertTrue(a.sameValue(b)); + assertTrue(a.isSubset(b)); + + b = factory.makeCopy(a); + assertTrue(a.sameValue(b)); + b.remove(1); + b.add(0); + assertTrue(!a.sameValue(b)); + + a = factory.parse("{1}"); + assertFalse(a.isSubset(b)); + b.remove(0); + assertFalse(a.isSubset(b)); + a.remove(1); + assertTrue(a.isEmpty()); + i = a.intersection(temp); + assertTrue(a.isEmpty()); + + temp2 = factory.make(); + assertTrue(temp2.sameValue(a)); + + a = factory.parse("{2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32,34,36,38,40,42,44,46,48,50,51,53,55,57,59,61,63}"); + b = factory.parse("{2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32,34,36,38,40,42,44,46,48,50,52,54,56,58,60,62}"); + MutableIntSet c = factory.parse("{2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32,34,36,38,40,42,44,46,48,50}"); + MutableIntSet d = factory.parse("{2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32,34,36,38,40,42,44,46,48,50}"); + MutableIntSet e = factory.parse("{2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32,34}"); + + assertTrue(e.isSubset(d)); + e.addAll(d); + assertTrue(e.isSubset(d)); + e.remove(12); + assertTrue(e.isSubset(d)); + e.add(105); + assertFalse(e.isSubset(d)); + + assertFalse(b.isSubset(a)); + + b.add(53); + assertFalse(b.isSubset(a)); + + a.add(52); + a.remove(52); + assertFalse(b.isSubset(a)); + + c.add(55); + assertFalse(c.isSubset(b)); + + d.add(53); + assertTrue(d.isSubset(b)); + + d = factory.make(); + d.copySet(c); + assertFalse(d.isSubset(b)); + + a = factory.parse("{2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32,34,36,38,40,42,44,46,48,50}"); + b = factory.parse("{2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32,34,36,38,40,42,44,46,48}"); + assertFalse(a.sameValue(b)); + b.add(50); + assertTrue(a.sameValue(b)); + a.add(11); + b.add(11); + assertTrue(a.sameValue(b)); + + a = factory.parse("{2,4,6,8,10,12,14,16,18,20,50}"); + b = factory.parse("{24,26,28,30,32,34,36,38,40,42,44,46,48}"); + c = factory.parse("{2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32,34,36,38,40,42,44,46,48,50}"); + a.addAll(b); + a.add(22); + assertTrue(a.sameValue(c)); + + a = factory.parse("{2,4,6,8,10,12,14,16,18,20,50}"); + b = factory.parse("{24,26,28,30,32,34,36,38,40,42,44,46,48}"); + c = factory.parse("{2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32,34,36,38,40,42,44,46,48,50}"); + b.addAll(factory.parse("{22}")); + a.addAll(b); + assertTrue(a.sameValue(c)); + + a = factory.parse("{2,4,6,8,10,12,14,16,18,20}"); + b = factory.parse("{22,24,26,28,30,32,34,36,38,40,42,44,46,48}"); + c = factory.parse("{2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32,34,36,38,40,42,44,46,48,50}"); + c.remove(22); + a.addAll(b); + assertFalse(a.sameValue(c)); + + a = factory.parse("{1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31,33,35,37,39,41,43,45,47,49,51,53,55,57,59}"); + System.out.println(a); // { 1 3 5 7 9 11 13 15 17 19 21 23 25 27 29 31 33 + // 35 + // 37 39 41 43 45 47 49 51 53 55 57 59 } + assertTrue(a.sameValue(a)); + i = a.intersection(temp); + assertTrue(i.sameValue(SparseIntSet.singleton(7))); + a.add(100); + assertTrue(a.sameValue(a)); + + b = factory.parse("{1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31,33,35,37,39,41,43,45,47,49,51,53,55,57,59,100}"); + assertTrue(a.sameValue(b)); + assertTrue(a.isSubset(b)); + + b = factory.makeCopy(a); + assertTrue(a.sameValue(b)); + b.remove(1); + b.add(0); + assertTrue(!a.sameValue(b)); + + a = factory.parse("{1}"); + assertFalse(a.isSubset(b)); + b.remove(0); + assertFalse(a.isSubset(b)); + a.remove(1); + assertTrue(a.isEmpty()); + i = a.intersection(temp); + assertTrue(a.isEmpty()); + + temp2 = factory.make(); + assertTrue(temp2.sameValue(a)); + } + + /** + * Test the MutableSharedBitVectorIntSet implementation + */ + public void testMutableSharedBitVectorIntSet() { + doMutableIntSet(new MutableSharedBitVectorIntSetFactory()); + } + + /** + * Test the MutableSparseIntSet implementation + */ + public void testMutableSparseIntSet() { + doMutableIntSet(new MutableSparseIntSetFactory()); + } + + /** + * Test the BimodalMutableSparseIntSet implementation + */ + public void testBimodalMutableSparseIntSet() { + doMutableIntSet(new BimodalMutableIntSetFactory()); + } + + /** + * Test the BitVectorIntSet implementation + */ + public void testBitVectorIntSet() { + doMutableIntSet(new BitVectorIntSetFactory()); + } + + public void testSmallMap() { + SmallMap M = new SmallMap(); + Integer I1 = new Integer(1); + Integer I2 = new Integer(2); + Integer I3 = new Integer(3); + M.put(I1, I1); + M.put(I2, I2); + M.put(I3, I3); + + Integer I = (Integer) M.get(new Integer(2)); + assertTrue(I != null); + assertTrue(I.equals(I2)); + + I = (Integer) M.get(new Integer(4)); + assertTrue(I == null); + + I = (Integer) M.put(new Integer(2), new Integer(3)); + assertTrue(I.equals(I2)); + I = (Integer) M.get(I2); + assertTrue(I.equals(I3)); + } + + public void testBimodalMap() { + Map M = new BimodalMap(3); + Integer I1 = new Integer(1); + Integer I2 = new Integer(2); + Integer I3 = new Integer(3); + Integer I4 = new Integer(4); + Integer I5 = new Integer(5); + Integer I6 = new Integer(6); + M.put(I1, I1); + M.put(I2, I2); + M.put(I3, I3); + + Integer I = M.get(new Integer(2)); + assertTrue(I != null); + assertTrue(I.equals(I2)); + + I = M.get(new Integer(4)); + assertTrue(I == null); + + I = M.put(new Integer(2), new Integer(3)); + assertTrue(I.equals(I2)); + I = M.get(I2); + assertTrue(I.equals(I3)); + + M.put(I4, I4); + M.put(I5, I5); + M.put(I6, I6); + I = M.get(new Integer(4)); + assertTrue(I != null); + assertTrue(I.equals(I4)); + + I = M.get(new Integer(7)); + assertTrue(I == null); + + I = M.put(new Integer(2), new Integer(6)); + assertTrue(I.equals(I3)); + I = M.get(I2); + assertTrue(I.equals(I6)); + } + + public void testBFSPathFinder() { + NumberedGraph G = makeBFSTestGraph(); + + // path from 0 to 8 + BFSPathFinder pf = new BFSPathFinder(G, G.getNode(0), G.getNode(8)); + List p = pf.find(); + + // path should be 8, 6, 4, 2, 0 + System.out.println("Path is " + p); + for (int i = 0; i < p.size(); i++) { + assertTrue((p.get(i)).intValue() == new int[] { 8, 6, 4, 2, 0 }[i]); + } + } + + public void testBoundedBFS() { + NumberedGraph G = makeBFSTestGraph(); + + BoundedBFSIterator bfs = new BoundedBFSIterator(G, G.getNode(0), 0); + Collection c = new Iterator2Collection(bfs); + assertTrue(c.size() == 1); + + bfs = new BoundedBFSIterator(G, G.getNode(0), 1); + c = new Iterator2Collection(bfs); + assertTrue(c.size() == 3); + + bfs = new BoundedBFSIterator(G, G.getNode(0), 2); + c = new Iterator2Collection(bfs); + assertTrue(c.size() == 5); + + bfs = new BoundedBFSIterator(G, G.getNode(0), 3); + c = new Iterator2Collection(bfs); + assertTrue(c.size() == 7); + + bfs = new BoundedBFSIterator(G, G.getNode(0), 4); + c = new Iterator2Collection(bfs); + assertTrue(c.size() == 9); + + bfs = new BoundedBFSIterator(G, G.getNode(0), 5); + c = new Iterator2Collection(bfs); + assertTrue(c.size() == 10); + + bfs = new BoundedBFSIterator(G, G.getNode(0), 500); + c = new Iterator2Collection(bfs); + assertTrue(c.size() == 10); + } + + private NumberedGraph makeBFSTestGraph() { + // test graph + NumberedGraph G = new SlowSparseNumberedGraph(); + + // add 10 nodes + Integer[] nodes = new Integer[10]; + for (int i = 0; i < nodes.length; i++) + G.addNode(nodes[i] = new Integer(i)); + + // edges to i-1, i+1, i+2 + for (int i = 0; i < nodes.length; i++) { + if (i > 0) { + G.addEdge(nodes[i], nodes[i - 1]); + } + if (i < nodes.length - 1) { + G.addEdge(nodes[i], nodes[i + 1]); + if (i < nodes.length - 2) { + G.addEdge(nodes[i], nodes[i + 2]); + } + } + } + return G; + } + + public void testDominatorsA() { + // test graph + Graph G = new SlowSparseNumberedGraph(); + + // add nodes + Object[] nodes = new Object[11]; + for (int i = 0; i < nodes.length; i++) + G.addNode(nodes[i] = new Integer(i)); + + // add edges + G.addEdge(nodes[10], nodes[0]); + G.addEdge(nodes[10], nodes[1]); + G.addEdge(nodes[0], nodes[2]); + G.addEdge(nodes[1], nodes[3]); + G.addEdge(nodes[2], nodes[5]); + G.addEdge(nodes[3], nodes[5]); + G.addEdge(nodes[4], nodes[2]); + G.addEdge(nodes[5], nodes[8]); + G.addEdge(nodes[6], nodes[3]); + G.addEdge(nodes[7], nodes[4]); + G.addEdge(nodes[8], nodes[7]); + G.addEdge(nodes[8], nodes[9]); + G.addEdge(nodes[9], nodes[6]); + + // compute dominators + Dominators D = new Dominators(G, nodes[10]); + + // assertions + int i = 0; + Object[] desired4 = new Object[] { nodes[4], nodes[7], nodes[8], nodes[5], nodes[10] }; + for (Iterator d4 = D.dominators(nodes[4]); d4.hasNext();) + assertTrue(d4.next() == desired4[i++]); + + int j = 0; + Object[] desired5 = new Object[] { nodes[8] }; + for (Iterator t4 = D.dominatorTree().getSuccNodes(nodes[5]); t4.hasNext();) + assertTrue(t4.next() == desired5[j++]); + + assertTrue(D.dominatorTree().getSuccNodeCount(nodes[10]) == 5); + } + + public void testBinaryIntegerRelation() { + byte[] impl = new byte[] { BasicNonNegativeIntRelation.SIMPLE, BasicNonNegativeIntRelation.TWO_LEVEL, + BasicNonNegativeIntRelation.SIMPLE }; + IBinaryNonNegativeIntRelation R = new BasicNonNegativeIntRelation(impl, BasicNonNegativeIntRelation.TWO_LEVEL); + R.add(3, 5); + R.add(3, 7); + R.add(3, 9); + R.add(3, 11); + R.add(5, 1); + int count = 0; + for (Iterator it = R.iterator(); it.hasNext();) { + System.err.println(it.next()); + count++; + } + assertTrue(count == 5); + + IntSet x = R.getRelated(3); + assertTrue(x.size() == 4); + + x = R.getRelated(5); + assertTrue(x.size() == 1); + + R.remove(5, 1); + x = R.getRelated(5); + assertTrue(x == null); + + R.add(2, 1); + R.add(2, 2); + R.remove(2, 1); + x = R.getRelated(2); + assertTrue(x.size() == 1); + + R.removeAll(3); + x = R.getRelated(3); + assertTrue(x == null); + + x = R.getRelated(0); + assertTrue(x == null); + + for (int i = 0; i < 100; i++) { + R.add(1, i); + } + assertTrue(R.getRelated(1).size() == 100); + R.remove(1, 1); + assertTrue(R.getRelated(1).size() == 99); + } + + public void testUnionFind() { + int SIZE = 10000; + IntegerUnionFind uf = new IntegerUnionFind(SIZE); + int count = countEquivalenceClasses(uf); + assertTrue("Got count " + count, count == SIZE); + + uf.union(3, 7); + assertTrue(uf.find(3) == uf.find(7)); + assertTrue("Got uf.find(3)=" + uf.find(3), uf.find(3) == 3 || uf.find(3) == 7); + + uf.union(7, SIZE - 1); + assertTrue(uf.find(3) == uf.find(SIZE - 1)); + assertTrue("Got uf.find(3)=" + uf.find(3), uf.find(3) == 3 || uf.find(3) == 7 || uf.find(3) == SIZE - 1); + + for (int i = 0; i < SIZE - 1; i++) { + uf.union(i, i + 1); + } + count = countEquivalenceClasses(uf); + assertTrue("Got count " + count, count == 1); + + uf = new IntegerUnionFind(SIZE); + for (int i = 0; i < SIZE; i++) { + if ((i % 2) == 0) { + uf.union(i, 0); + } else { + uf.union(i, 1); + } + } + count = countEquivalenceClasses(uf); + assertTrue("Got count " + count, count == 2); + } + + private int countEquivalenceClasses(IntegerUnionFind uf) { + HashSet s = new HashSet(); + for (int i = 0; i < uf.size(); i++) { + s.add(new Integer(uf.find(i))); + } + return s.size(); + } + + public void testBitVectors() { + BitVector bv = new BitVector(); + + // does the following not automatically scale the bitvector to + // a reasonable size? + bv.set(55); + + assertTrue(bv.max() == 55); + assertTrue(bv.get(55)); + + bv.set(59); + assertTrue(bv.max() == 59); + assertTrue(bv.get(55)); + assertTrue(bv.get(59)); + + { + boolean[] gets = new boolean[] { false, true, true }; + int[] bits = new int[] { 0, 55, 59 }; + for (int i = 0, j = 0; i != -1; i = bv.nextSetBit(i + 1), j++) { + assertTrue(i == bits[j]); + assertTrue(bv.get(i) == gets[j]); + } + } + + bv.set(77); + + assertTrue(bv.max() == 77); + { + boolean[] gets = new boolean[] { false, true, true, true }; + int[] bits = new int[] { 0, 55, 59, 77 }; + for (int i = 0, j = 0; i != -1; i = bv.nextSetBit(i + 1), j++) { + assertTrue(i == bits[j]); + assertTrue(bv.get(i) == gets[j]); + } + } + + bv.set(3); + assertTrue(bv.max() == 77); + { + boolean[] gets = new boolean[] { false, true, true, true, true }; + int[] bits = new int[] { 0, 3, 55, 59, 77 }; + for (int i = 0, j = 0; i != -1; i = bv.nextSetBit(i + 1), j++) { + assertTrue(i == bits[j]); + assertTrue(bv.get(i) == gets[j]); + } + } + + System.out.println(bv); + } +} diff --git a/com.ibm.wala.core.tests/com.ibm.wala.core.tests/src/com/ibm/wala/core/tests/callGraph/CallGraphTest.java b/com.ibm.wala.core.tests/com.ibm.wala.core.tests/src/com/ibm/wala/core/tests/callGraph/CallGraphTest.java new file mode 100644 index 000000000..8fe18a260 --- /dev/null +++ b/com.ibm.wala.core.tests/com.ibm.wala.core.tests/src/com/ibm/wala/core/tests/callGraph/CallGraphTest.java @@ -0,0 +1,567 @@ +/******************************************************************************* + * Copyright (c) 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.core.tests.callGraph; + +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; + +import org.eclipse.emf.ecore.EObject; + +import com.ibm.wala.cfg.CFGCache; +import com.ibm.wala.cfg.IBasicBlock; +import com.ibm.wala.core.tests.util.TestConstants; +import com.ibm.wala.core.tests.util.WalaTestCase; +import com.ibm.wala.ecore.java.ECallSite; +import com.ibm.wala.ecore.java.EJavaMethod; +import com.ibm.wala.ecore.java.impl.JavaPackageImpl; +import com.ibm.wala.emf.wrappers.ECallGraphWrapper; +import com.ibm.wala.emf.wrappers.EMFBridge; +import com.ibm.wala.ipa.callgraph.AnalysisOptions; +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.CallGraphStats; +import com.ibm.wala.ipa.callgraph.Entrypoints; +import com.ibm.wala.ipa.callgraph.impl.AllApplicationEntrypoints; +import com.ibm.wala.ipa.callgraph.impl.Util; +import com.ibm.wala.ipa.cfg.BasicBlockInContext; +import com.ibm.wala.ipa.cfg.InterproceduralCFG; +import com.ibm.wala.ipa.cha.ClassHierarchy; +import com.ibm.wala.ipa.cha.ClassHierarchyException; +import com.ibm.wala.types.MethodReference; +import com.ibm.wala.util.collections.HashSetFactory; +import com.ibm.wala.util.debug.Assertions; +import com.ibm.wala.util.debug.Trace; +import com.ibm.wala.util.graph.Graph; +import com.ibm.wala.util.graph.GraphIntegrity; +import com.ibm.wala.util.graph.GraphIntegrity.UnsoundGraphException; +import com.ibm.wala.util.graph.traverse.DFS; +import com.ibm.wala.util.warnings.CallGraphWarnings; +import com.ibm.wala.util.warnings.WarningSet; + +/** + * + * Tests for Call Graph construction + * + * @author sfink + */ + +public class CallGraphTest extends WalaTestCase { + + static { + JavaPackageImpl.init(); + } + + private static final String[] IGNORE_STRINGS = { "finalize", "java.lang.ThreadLocal", "java.lang.ref.Reference.get()" }; + + public static void main(String[] args) { + justThisTest(CallGraphTest.class); + } + + /** + * Constructor for SpecJTest. + * + * @param arg0 + */ + public CallGraphTest(String arg0) { + super(arg0); + } + + /* + * public void testOpenccg() { AnalysisScope scope = + * CallGraphTestUtil.makeJ2SEAnalysisScope(Config.OPENCCG); WarningSet + * warnings = new WarningSet(); ClassHierarchy cha = + * ClassHierarchy.buildClassHierarchy(scope, warnings); Entrypoints + * entrypoints = + * com.ibm.wala.ipa.callgraph.impl.Util.makeMainEntrypoints(scope, cha, + * Config.OPENCCG_CROSS_VALIDATE_REALIZER); AnalysisOptions options = + * CallGraphTestUtil.makeAnalysisOptions(scope, entrypoints); + * + * Trace.println("OPENCCG Cross Validate Realizer set up warnings:\n"); + * Trace.print(warnings.toString()); + * + * doCallGraphs(options, cha, scope, null, useShortProfile(), false); } + * + * public void testKaba() { AnalysisScope scope = + * CallGraphTestUtil.makeJ2SEAnalysisScope(Config.KABA); WarningSet warnings = + * new WarningSet(); ClassHierarchy cha = + * ClassHierarchy.buildClassHierarchy(scope, warnings); Entrypoints + * entrypoints = + * com.ibm.wala.ipa.callgraph.impl.Util.makeMainEntrypoints(scope, cha, + * Config.KABA_MAIN); AnalysisOptions options = + * CallGraphTestUtil.makeAnalysisOptions(scope, entrypoints); + * + * Trace.println("kaba verifier set up warnings:\n"); + * Trace.print(warnings.toString()); + * + * doCallGraphs(options, cha, scope, null, useShortProfile(), false); } + * + * public void testAntlr() { AnalysisScope scope = + * CallGraphTestUtil.makeJ2SEAnalysisScope(Config.ANTLR); WarningSet warnings = + * new WarningSet(); ClassHierarchy cha = + * ClassHierarchy.buildClassHierarchy(scope, warnings); Entrypoints + * entrypoints = + * com.ibm.wala.ipa.callgraph.impl.Util.makeMainEntrypoints(scope, cha, + * Config.ANTLR_MAIN); AnalysisOptions options = + * CallGraphTestUtil.makeAnalysisOptions(scope, entrypoints); + * + * Trace.println("ANTLR verifier set up warnings:\n"); + * Trace.print(warnings.toString()); + * + * doCallGraphs(options, cha, scope, null, useShortProfile(), false); } + */ + + public void testBcelVerifier() throws ClassHierarchyException { + AnalysisScope scope = CallGraphTestUtil.makeJ2SEAnalysisScope(TestConstants.BCEL); + WarningSet warnings = new WarningSet(); + ClassHierarchy cha = ClassHierarchy.make(scope, warnings); + Entrypoints entrypoints = com.ibm.wala.ipa.callgraph.impl.Util + .makeMainEntrypoints(scope, cha, TestConstants.BCEL_VERIFIER_MAIN); + AnalysisOptions options = CallGraphTestUtil.makeAnalysisOptions(scope, entrypoints); + + Trace.println("bcel verifier set up warnings:\n"); + Trace.print(warnings.toString()); + + doCallGraphs(options, cha, scope, null, useShortProfile(), false); + } + + public void testJava_cup() throws ClassHierarchyException { + AnalysisScope scope = CallGraphTestUtil.makeJ2SEAnalysisScope(TestConstants.JAVA_CUP); + WarningSet warnings = new WarningSet(); + ClassHierarchy cha = ClassHierarchy.make(scope, warnings); + Entrypoints entrypoints = com.ibm.wala.ipa.callgraph.impl.Util.makeMainEntrypoints(scope, cha, TestConstants.JAVA_CUP_MAIN); + AnalysisOptions options = CallGraphTestUtil.makeAnalysisOptions(scope, entrypoints); + + Trace.println("java_cup set up warnings:\n"); + Trace.print(warnings.toString()); + + doCallGraphs(options, cha, scope, null, useShortProfile(), false); + } + + public void testJLex() throws ClassHierarchyException { + AnalysisScope scope = CallGraphTestUtil.makeJ2SEAnalysisScope(TestConstants.JLEX); + WarningSet warnings = new WarningSet(); + ClassHierarchy cha = ClassHierarchy.make(scope, warnings); + Entrypoints entrypoints = com.ibm.wala.ipa.callgraph.impl.Util.makeMainEntrypoints(scope, cha, TestConstants.JLEX_MAIN); + AnalysisOptions options = CallGraphTestUtil.makeAnalysisOptions(scope, entrypoints); + + Trace.println("JLex set up warnings:\n"); + Trace.print(warnings.toString()); + + doCallGraphs(options, cha, scope, null, useShortProfile(), false); + } + + public void testCornerCases() throws ClassHierarchyException { + AnalysisScope scope = CallGraphTestUtil.makeJ2SEAnalysisScope(TestConstants.WALA_TESTDATA); + WarningSet warnings = new WarningSet(); + ClassHierarchy cha = ClassHierarchy.make(scope, warnings); + Entrypoints entrypoints = new AllApplicationEntrypoints(scope, cha); + AnalysisOptions options = CallGraphTestUtil.makeAnalysisOptions(scope, entrypoints); + + Trace.println("testCornerCases set up warnings:\n"); + Trace.print(warnings.toString()); + + warnings = doCallGraphs(options, cha, scope, null, useShortProfile(), false); + + // we expect a warning or two about class Abstract1, which has no concrete + // subclasses + String ws = warnings.toString(); + assertTrue("failed to report a warning about Abstract1", ws.indexOf("cornerCases/Abstract1") > -1); + + // we do not expect a warning about class Abstract2, which has a concrete + // subclasses + assertTrue("reported a warning about Abstract2", ws.indexOf("cornerCases/Abstract2") == -1); + } + + // + // public void testSPECjvm98() { + // AnalysisScope scope = CGTUtils.makeJ2SEAnalysisScope(Config.SPECJVM); + // + // // temporary hack because 1.5 libraries still cause grief + // if (scope.isJava15Libraries()) { + // scope = CGTUtils.makeJ2EEAnalysisScope(Config.SPECJVM); + // } + // + // WarningSet warnings = new WarningSet(); + // ClassHierarchy cha = ClassHierarchy.buildClassHierarchy(scope, warnings); + // Entrypoints entrypoints = + // com.ibm.wala.ipa.callgraph.impl.Util.makeMainEntrypoints(scope, cha, + // Config.SPECJVM_MAIN); + // AnalysisOptions options = CGTUtils.makeAnalysisOptions(scope, entrypoints); + // + // Trace.println("SPECjvm98 set up warnings:\n"); + // Trace.print(warnings.toString()); + // + // doCallGraphs(options, cha, scope, Config.SPECJVM_DCG, false, false); + // } + // + public void testHello() throws ClassHierarchyException { + AnalysisScope scope = CallGraphTestUtil.makeJ2SEAnalysisScope(TestConstants.HELLO); + WarningSet warnings = new WarningSet(); + ClassHierarchy cha = ClassHierarchy.make(scope, warnings); + Entrypoints entrypoints = com.ibm.wala.ipa.callgraph.impl.Util.makeMainEntrypoints(scope, cha, TestConstants.HELLO_MAIN); + AnalysisOptions options = CallGraphTestUtil.makeAnalysisOptions(scope, entrypoints); + + Trace.println("hello set up warnings:\n"); + Trace.print(warnings.toString()); + + doCallGraphs(options, cha, scope, null, false, false); + } + + public void testRecursion() throws ClassHierarchyException { + AnalysisScope scope = CallGraphTestUtil.makeJ2SEAnalysisScope(TestConstants.WALA_TESTDATA); + WarningSet warnings = new WarningSet(); + ClassHierarchy cha = ClassHierarchy.make(scope, warnings); + Entrypoints entrypoints = com.ibm.wala.ipa.callgraph.impl.Util.makeMainEntrypoints(scope, cha, TestConstants.RECURSE_MAIN); + AnalysisOptions options = CallGraphTestUtil.makeAnalysisOptions(scope, entrypoints); + + Trace.println("testRecursion set up warnings:\n"); + Trace.print(warnings.toString()); + + doCallGraphs(options, cha, scope, null, useShortProfile(), false); + } + + public void testHelloAllEntrypoints() throws ClassHierarchyException { + AnalysisScope scope = CallGraphTestUtil.makeJ2SEAnalysisScope(TestConstants.HELLO); + WarningSet warnings = new WarningSet(); + ClassHierarchy cha = ClassHierarchy.make(scope, warnings); + Entrypoints entrypoints = new AllApplicationEntrypoints(scope, cha); + AnalysisOptions options = CallGraphTestUtil.makeAnalysisOptions(scope, entrypoints); + + Trace.println("hello all entrypoints set up warnings:\n"); + Trace.print(warnings.toString()); + + doCallGraphs(options, cha, scope, null, useShortProfile(), false); + } + + // + // public void testSPECjvm98AllEntrypoints() { + // AnalysisScope scope = CGTUtils.makeJ2SEAnalysisScope(Config.SPECJVM); + // WarningSet warnings = new WarningSet(); + // ClassHierarchy cha = ClassHierarchy.buildClassHierarchy(scope, warnings); + // Entrypoints entrypoints = new AllApplicationEntrypoints(scope, cha); + // AnalysisOptions options = CGTUtils.makeAnalysisOptions(scope, entrypoints); + // + // Trace.println("SPECjvm98 set up warnings:\n"); + // Trace.print(warnings.toString()); + // + // doCallGraphs(options, cha, scope, null, useShortProfile(), true); + // } + + /** + * TODO: refactor this to avoid excessive code bloat. + */ + public static WarningSet doCallGraphs(AnalysisOptions options, ClassHierarchy cha, AnalysisScope scope, String dcgFile, + boolean stopAfterZeroCFA, boolean stopAfterZeroContainerCFA) { + + // /////////////// + // // RTA ///// + // /////////////// + WarningSet warnings = new WarningSet(); + CallGraph cg = CallGraphTestUtil.buildRTA(options, cha, scope, warnings); + try { + GraphIntegrity.check(cg); + } catch (UnsoundGraphException e1) { + e1.printStackTrace(); + assertTrue(e1.getMessage(), false); + } + Set rtaMethods = CallGraphStats.collectMethods(cg); + Trace.println("RTA methods reached: " + rtaMethods.size()); + Trace.println(CallGraphStats.getStats(cg)); + Trace.println("RTA warnings:\n"); + warnings.addAll(CallGraphWarnings.getWarnings(cg)); + Trace.print(warnings.toString(cg)); + + // /////////////// + // // 0-CFA ///// + // /////////////// + warnings = new WarningSet(); + cg = CallGraphTestUtil.buildZeroCFA(options, cha, scope, warnings); + + // FIXME: annoying special cases caused by clone2assign mean using + // the rta graph for proper graph subset checking does not work. + // (note that all the other such checks do use proper graph subset) + Graph squashZero = checkCallGraph(warnings, cg, null, rtaMethods, "0-CFA"); + + // test Pretransitive 0-CFA + // not currently supported + // warnings = new WarningSet(); + // options.setUsePreTransitiveSolver(true); + // CallGraph cgP = CallGraphTestUtil.buildZeroCFA(options, cha, scope, + // warnings); + // options.setUsePreTransitiveSolver(false); + // Graph squashPT = checkCallGraph(warnings, cgP, squashZero, null, "Pre-T + // 1"); + // checkCallGraph(warnings, cg, squashPT, null, "Pre-T 2"); + + if (stopAfterZeroCFA) { + return warnings; + } + // /////////////// + // // 0-1-CFA /// + // /////////////// + warnings = new WarningSet(); + cg = CallGraphTestUtil.buildZeroOneCFA(options, cha, scope, warnings); + Graph squashZeroOne = checkCallGraph(warnings, cg, squashZero, null, "0-1-CFA"); + + // /////////////////////////////////////////////////// + // // 0-CFA augmented to disambiguate containers /// + // /////////////////////////////////////////////////// + warnings = new WarningSet(); + cg = CallGraphTestUtil.buildZeroContainerCFA(options, cha, scope, warnings); + Graph squashZeroContainer = checkCallGraph(warnings, cg, squashZero, null, "0-Container-CFA"); + + if (stopAfterZeroContainerCFA) + return warnings; + + // /////////////////////////////////////////////////// + // // 0-1-CFA augmented to disambiguate containers /// + // /////////////////////////////////////////////////// + warnings = new WarningSet(); + cg = CallGraphTestUtil.buildZeroOneContainerCFA(options, cha, scope, warnings); + checkCallGraph(warnings, cg, squashZeroContainer, null, "0-1-Container-CFA"); + checkCallGraph(warnings, cg, squashZeroOne, null, "0-1-Container-CFA"); + + if (dcgFile != null) { + checkAgainstDCG(cg, dcgFile); + } + + // test ICFG + checkICFG(cg, options.getCFGCache()); + return warnings; + // ///////////// + // // 1-CFA /// + // ///////////// + // warnings = new WarningSet(); + // cg = buildOneCFA(); + + } + + /** + * Check properties of the InterproceduralCFG + * + * @param cg + */ + private static void checkICFG(CallGraph cg, CFGCache cfgCache) { + InterproceduralCFG icfg = new InterproceduralCFG(cg, cfgCache, new WarningSet()); + + try { + GraphIntegrity.check(icfg); + } catch (UnsoundGraphException e) { + e.printStackTrace(); + assertTrue(false); + } + + // perform a little icfg exercise + int count = 0; + for (Iterator it = icfg.iterateNodes(); it.hasNext();) { + IBasicBlock bb = (IBasicBlock) it.next(); + if (icfg.hasCall((BasicBlockInContext) bb)) { + count++; + } + } + } + + /** + * Check that cg is a superset of the dynamic call graph encoded in the + * dcgFile + * + * @param cg + * @param dcgFile + */ + private static void checkAgainstDCG(CallGraph cg, String dcgFile) { + + Set synthLeaves = getSyntheticLeaves(cg); + + com.ibm.wala.emf.wrappers.ECallGraphWrapper subG = com.ibm.wala.emf.wrappers.ECallGraphWrapper.load(dcgFile, + CallGraphTest.class.getClassLoader()); + com.ibm.wala.emf.wrappers.ECallGraphWrapper superG = EMFBridge.makeCallGraph(cg); + + prune(subG, synthLeaves); + prune(superG, synthLeaves); + + checkGraphSubset(superG, subG); + } + + /** + * @param superG + * @param subG + */ + public static void checkGraphSubset(ECallGraphWrapper superG, ECallGraphWrapper subG) { + Set nodeDiff = Util.setify(subG.iterateNodes()); + nodeDiff.removeAll(Util.setify(superG.iterateNodes())); + Set toRemove = HashSetFactory.make(); + for (Iterator it = nodeDiff.iterator(); it.hasNext();) { + EObject o = it.next(); + if (o instanceof ECallSite) { + toRemove.add(o); + } + } + // a bogus hack: ignore some stuff in the dcg that we haven't + // cleaned out; TODO: figure out what's happening and delete this + outer: for (Iterator it = nodeDiff.iterator(); it.hasNext();) { + EObject o = it.next(); + for (int i = 0; i < IGNORE_STRINGS.length; i++) { + if (o.toString().indexOf(IGNORE_STRINGS[i]) > -1) { + toRemove.add(o); + continue outer; + } + } + } + nodeDiff.removeAll(toRemove); + + if (!nodeDiff.isEmpty()) { + Trace.println("supergraph: "); + Trace.println(superG.toString()); + Trace.println("subgraph: "); + Trace.println(subG.toString()); + Trace.println("nodeDiff: "); + for (Iterator it = nodeDiff.iterator(); it.hasNext();) { + Trace.println(it.next().toString()); + } + Assertions.productionAssertion(nodeDiff.isEmpty(), "bad superset, see tracefile\n"); + } + } + + /** + *
    + *
  • remove all methods from G that correspond to synthetic methods + *
  • remove all nodes from G that are no longer reachable from the fake + * root. + *
      + * + * @param G + * an EMF format call graph + * @param synthetic + * a set of synthetic methods + */ + private static void prune(ECallGraphWrapper G, Set synthetic) { + // compute synthetic nodes + Set toRemove = HashSetFactory.make(); + for (Iterator it = synthetic.iterator(); it.hasNext();) { + CGNode n = it.next(); + EJavaMethod node = EMFBridge.makeJavaMethod(n.getMethod().getReference()); + if (node != null) { + toRemove.add(node); + } + } + + removeNodes(G, toRemove); + + // compute nodes reachable from the fake root + EJavaMethod fakeRoot = EMFBridge.makeFakeRootMethod(); + Assertions._assert(fakeRoot != null); + Collection c = DFS.getReachableNodes(G, Collections.singleton(fakeRoot)); + + // remove other nodes + toRemove = HashSetFactory.make(); + for (Iterator it = G.iterateNodes(); it.hasNext();) { + EObject n = it.next(); + if (!c.contains(n)) { + toRemove.add(n); + } + } + removeNodes(G, toRemove); + + // remove call site nodes with no targets (these won't appear in the dcg) + toRemove = HashSetFactory.make(); + for (Iterator it = G.iterateNodes(); it.hasNext();) { + EObject n = it.next(); + if (n instanceof ECallSite) { + if (G.getSuccNodeCount(n) == 0) { + toRemove.add(n); + } + } + } + removeNodes(G, toRemove); + + } + + /** + * @param G + * @param toRemove + */ + private static void removeNodes(ECallGraphWrapper G, Set toRemove) { + // remove all these nodes + for (Iterator it = toRemove.iterator(); it.hasNext();) { + EObject n = it.next(); + if (G.containsNode(n)) { + G.removeNodeAndEdges(n); + } + } + } + + /** + * @param cg + * @return Set in cg that are synthetic and have no call sites + */ + private static Set getSyntheticLeaves(CallGraph cg) { + HashSet result = HashSetFactory.make(); + for (Iterator it = cg.iterateNodes(); it.hasNext();) { + CGNode node = (CGNode) it.next(); + if (!node.equals(cg.getFakeRootNode())) { + if (node.getMethod().isSynthetic()) { + if (!node.iterateSites().hasNext()) { + result.add(node); + } + } + } + } + return result; + } + + /** + * Check consistency of a callgraph, and check that this call graph is a + * subset of a super-graph + * + * @param warnings + * object to track warnings + * @param cg + * @param superCG + * @param superMethods + * @param thisAlgorithm + * @return a squashed version of cg + */ + private static Graph checkCallGraph(WarningSet warnings, CallGraph cg, Graph superCG, + Set superMethods, String thisAlgorithm) { + try { + GraphIntegrity.check(cg); + } catch (UnsoundGraphException e1) { + assertTrue(e1.getMessage(), false); + } + Set callGraphMethods = CallGraphStats.collectMethods(cg); + Trace.println(thisAlgorithm + " methods reached: " + callGraphMethods.size()); + Trace.println(CallGraphStats.getStats(cg)); + Trace.println(thisAlgorithm + " warnings:\n"); + warnings.addAll(CallGraphWarnings.getWarnings(cg)); + Trace.print(warnings.toString(cg)); + + Graph thisCG = com.ibm.wala.ipa.callgraph.impl.Util.squashCallGraph(thisAlgorithm, cg); + + if (superCG != null) { + com.ibm.wala.ipa.callgraph.impl.Util.checkGraphSubset(superCG, thisCG); + } else { + if (!superMethods.containsAll(callGraphMethods)) { + Set temp = HashSetFactory.make(); + temp.addAll(callGraphMethods); + temp.removeAll(superMethods); + Trace.printCollection("Violations", temp); + Assertions.UNREACHABLE(); + } + } + + return thisCG; + } + +} diff --git a/com.ibm.wala.core.tests/com.ibm.wala.core.tests/src/com/ibm/wala/core/tests/callGraph/CallGraphTestUtil.java b/com.ibm.wala.core.tests/com.ibm.wala.core.tests/src/com/ibm/wala/core/tests/callGraph/CallGraphTestUtil.java new file mode 100644 index 000000000..2122fdb53 --- /dev/null +++ b/com.ibm.wala.core.tests/com.ibm.wala.core.tests/src/com/ibm/wala/core/tests/callGraph/CallGraphTestUtil.java @@ -0,0 +1,141 @@ +/******************************************************************************* + * 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.core.tests.callGraph; + +import com.ibm.wala.emf.wrappers.EMFScopeWrapper; +import com.ibm.wala.ipa.callgraph.AnalysisOptions; +import com.ibm.wala.ipa.callgraph.AnalysisScope; +import com.ibm.wala.ipa.callgraph.CallGraph; +import com.ibm.wala.ipa.callgraph.CallGraphBuilder; +import com.ibm.wala.ipa.callgraph.Entrypoints; +import com.ibm.wala.ipa.callgraph.impl.Util; +import com.ibm.wala.ipa.cha.ClassHierarchy; +import com.ibm.wala.util.Stopwatch; +import com.ibm.wala.util.debug.Trace; +import com.ibm.wala.util.warnings.WarningSet; + +/** + * + * Utilities for call graph tests + * + * @author sfink + */ +public class CallGraphTestUtil { + + private static final ClassLoader MY_CLASSLOADER = CallGraphTestUtil.class.getClassLoader(); + +// private static final String reflectionFile = Config.SPECJVM_REFLECTION; + + public static AnalysisOptions makeAnalysisOptions(AnalysisScope scope, Entrypoints entrypoints) { + AnalysisOptions options = new AnalysisOptions(scope, entrypoints); + +// InputStream rStream = CallGraphTestUtil.class.getClassLoader().getResourceAsStream(reflectionFile); +// ReflectionSpecification R = new XMLReflectionReader(rStream, scope); +// options.setReflectionSpec(R); + return options; + } + + + public static AnalysisScope makeJ2SEAnalysisScope(String scopeFile) { + return new EMFScopeWrapper(scopeFile, "J2SEClassHierarchyExclusions.xml", MY_CLASSLOADER); + } + + public static AnalysisScope makeJ2SEAnalysisScope(String scopeFile, String exclusionsFile) { + return new EMFScopeWrapper(scopeFile, exclusionsFile, MY_CLASSLOADER); + } + + public static CallGraph buildRTA(AnalysisOptions options, ClassHierarchy cha, AnalysisScope scope, WarningSet warnings) { + Stopwatch S = new Stopwatch("build RTA graph"); + S.start(); + + CallGraphBuilder builder = Util.makeRTABuilder(options, cha, scope, warnings); + CallGraph cg = builder.makeCallGraph(options); + + S.stop(); + Trace.println(S.report()); + return cg; + } + + public static CallGraph buildZeroCFA(AnalysisOptions options, ClassHierarchy cha, AnalysisScope scope, WarningSet warnings) { + Stopwatch S = new Stopwatch("build ZeroCFA graph"); + S.start(); + + CallGraphBuilder builder = Util.makeZeroCFABuilder(options, cha, scope, warnings); + CallGraph cg = builder.makeCallGraph(options); + + S.stop(); + Trace.println(S.report()); + return cg; + } + + public static CallGraph buildVanillaZeroOneCFA(AnalysisOptions options, ClassHierarchy cha, AnalysisScope scope, WarningSet warnings) { + Stopwatch S = new Stopwatch("build Vanila 0-1-CFA graph"); + S.start(); + + CallGraphBuilder builder = Util.makeVanillaZeroOneCFABuilder(options, cha, scope, warnings); + CallGraph cg = builder.makeCallGraph(options); + + S.stop(); + Trace.println(S.report()); + return cg; + } + + public static CallGraph buildZeroOneCFA(AnalysisOptions options, ClassHierarchy cha, AnalysisScope scope, WarningSet warnings) { + Stopwatch S = new Stopwatch("build 0-1-CFA graph"); + S.start(); + + CallGraphBuilder builder = Util.makeZeroOneCFABuilder(options, cha, scope, warnings); + CallGraph cg = builder.makeCallGraph(options); + + S.stop(); + Trace.println(S.report()); + return cg; + } + + public static CallGraph buildZeroContainerCFA(AnalysisOptions options, ClassHierarchy cha, AnalysisScope scope, + WarningSet warnings) { + Stopwatch S = new Stopwatch("build 0-1-Container-CFA graph"); + S.start(); + + CallGraphBuilder builder = Util.makeZeroContainerCFABuilder(options, cha, scope, warnings); + CallGraph cg = builder.makeCallGraph(options); + + S.stop(); + Trace.println(S.report()); + return cg; + } + + public static CallGraph buildZeroOneContainerCFA(AnalysisOptions options, ClassHierarchy cha, AnalysisScope scope, + WarningSet warnings) { + Stopwatch S = new Stopwatch("build 0-1-Container-CFA graph"); + S.start(); + + CallGraphBuilder builder = Util.makeZeroOneContainerCFABuilder(options, cha, scope, warnings); + CallGraph cg = builder.makeCallGraph(options); + + S.stop(); + Trace.println(S.report()); + return cg; + } + + public static CallGraph buildOneCFA(AnalysisOptions options, ClassHierarchy cha, AnalysisScope scope, WarningSet warnings) { + Stopwatch S = new Stopwatch("build 1-CFA graph"); + S.start(); + + CallGraphBuilder builder = Util.makeOneCFABuilder(options, cha, MY_CLASSLOADER, scope, warnings); + CallGraph cg = builder.makeCallGraph(options); + + S.stop(); + Trace.println(S.report()); + return cg; + } + +} diff --git a/com.ibm.wala.core.tests/com.ibm.wala.core.tests/src/com/ibm/wala/core/tests/callGraph/ClassConstantTest.java b/com.ibm.wala.core.tests/com.ibm.wala.core.tests/src/com/ibm/wala/core/tests/callGraph/ClassConstantTest.java new file mode 100644 index 000000000..c6486d19a --- /dev/null +++ b/com.ibm.wala.core.tests/com.ibm.wala.core.tests/src/com/ibm/wala/core/tests/callGraph/ClassConstantTest.java @@ -0,0 +1,77 @@ +/******************************************************************************* + * 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.core.tests.callGraph; + +import java.util.Set; + +import junit.framework.Assert; + +import com.ibm.wala.core.tests.util.TestConstants; +import com.ibm.wala.core.tests.util.WalaTestCase; +import com.ibm.wala.ipa.callgraph.AnalysisOptions; +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.Entrypoints; +import com.ibm.wala.ipa.callgraph.impl.Util; +import com.ibm.wala.ipa.cha.ClassHierarchy; +import com.ibm.wala.ipa.cha.ClassHierarchyException; +import com.ibm.wala.types.ClassLoaderReference; +import com.ibm.wala.types.MethodReference; +import com.ibm.wala.types.TypeReference; +import com.ibm.wala.util.debug.Trace; +import com.ibm.wala.util.warnings.WarningSet; + +/** + * Check handling of class constants (test for part of 1.5 support) + * + * @author Julian Dolby (dolby@us.ibm.com) + */ +public class ClassConstantTest extends WalaTestCase { + + public void testClassConstants() throws ClassHierarchyException { + + AnalysisScope scope = CallGraphTestUtil.makeJ2SEAnalysisScope(TestConstants.WALA_TESTDATA); + WarningSet warnings = new WarningSet(); + ClassHierarchy cha = ClassHierarchy.make(scope, warnings); + Trace.println("setup warnings:"); + Trace.println(warnings); + + // make sure we have the test class + TypeReference mainClassRef = TypeReference.findOrCreate(ClassLoaderReference.Application, TestConstants.CLASSCONSTANT_MAIN); + Assert.assertTrue(cha.lookupClass(mainClassRef) != null); + + // make call graph + Entrypoints entrypoints = Util.makeMainEntrypoints(scope, cha, TestConstants.CLASSCONSTANT_MAIN); + AnalysisOptions options = CallGraphTestUtil.makeAnalysisOptions(scope, entrypoints); + CallGraph cg = CallGraphTestUtil.buildZeroCFA(options, cha, scope, warnings); + Trace.println("\nCall graph:"); + Trace.println(cg); + + // make sure the main method is reached + MethodReference mainMethodRef = MethodReference.findOrCreate(mainClassRef, "main", "([Ljava/lang/String;)V"); + Set mainMethodNodes = cg.getNodes(mainMethodRef); + Assert.assertFalse(mainMethodNodes.isEmpty()); + CGNode mainMethodNode = (CGNode) mainMethodNodes.iterator().next(); + Trace.println("main IR:"); + Trace.println(cg.getInterpreter(mainMethodNode).getIR(mainMethodNode, warnings)); + + // Make sure call to hashCode is there (it uses the class constant) + TypeReference classRef = TypeReference.findOrCreate(ClassLoaderReference.Primordial, "Ljava/lang/Class"); + MethodReference hashCodeRef = MethodReference.findOrCreate(classRef, "hashCode", "()I"); + Set hashCodeNodes = cg.getNodes(hashCodeRef); + Assert.assertFalse(hashCodeNodes.isEmpty()); + + // make sure call to hashCode from main + Assert.assertTrue(cg.hasEdge(mainMethodNode, hashCodeNodes.iterator().next())); + } + +} diff --git a/com.ibm.wala.core.tests/com.ibm.wala.core.tests/src/com/ibm/wala/core/tests/callGraph/CloneTest.java b/com.ibm.wala.core.tests/com.ibm.wala.core.tests/src/com/ibm/wala/core/tests/callGraph/CloneTest.java new file mode 100644 index 000000000..0fddc56ae --- /dev/null +++ b/com.ibm.wala.core.tests/com.ibm.wala.core.tests/src/com/ibm/wala/core/tests/callGraph/CloneTest.java @@ -0,0 +1,72 @@ +/******************************************************************************* + * Copyright (c) 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.core.tests.callGraph; + +import java.util.Iterator; +import java.util.Set; + +import com.ibm.wala.classLoader.CallSiteReference; +import com.ibm.wala.core.tests.util.TestConstants; +import com.ibm.wala.core.tests.util.WalaTestCase; +import com.ibm.wala.ipa.callgraph.AnalysisOptions; +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.Entrypoints; +import com.ibm.wala.ipa.callgraph.impl.AllApplicationEntrypoints; +import com.ibm.wala.ipa.cha.ClassHierarchy; +import com.ibm.wala.ipa.cha.ClassHierarchyException; +import com.ibm.wala.types.ClassLoaderReference; +import com.ibm.wala.types.MethodReference; +import com.ibm.wala.types.TypeReference; +import com.ibm.wala.util.warnings.WarningSet; + +/** + * Check properties of a call to clone() in RTA + * + * @author Bruno Dufour + */ +public class CloneTest extends WalaTestCase { + + public void testClone() throws ClassHierarchyException { + + AnalysisScope scope = CallGraphTestUtil.makeJ2SEAnalysisScope(TestConstants.WALA_TESTDATA); + WarningSet warnings = new WarningSet(); + ClassHierarchy cha = ClassHierarchy.make(scope, warnings); + Entrypoints entrypoints = new AllApplicationEntrypoints(scope, cha); + AnalysisOptions options = CallGraphTestUtil.makeAnalysisOptions(scope, entrypoints); + + CallGraph cg = CallGraphTestUtil.buildRTA(options, cha, scope, warnings); + + // Find node corresp. to java.text.MessageFormat.clone() + TypeReference t = TypeReference.findOrCreate(ClassLoaderReference.Primordial, "Ljava/text/MessageFormat"); + MethodReference m = MethodReference.findOrCreate(t, "clone", "()Ljava/lang/Object;"); + CGNode node = (CGNode) cg.getNodes(m).iterator().next(); + + // Check there's exactly one target for each super call in + // MessageFormat.clone() + for (Iterator i = node.iterateSites(); i.hasNext();) { + CallSiteReference site = (CallSiteReference) i.next(); + if (site.isSpecial()) { + if (site.getDeclaredTarget().getDeclaringClass().equals(TypeReference.JavaLangObject)) { + Set targets = node.getPossibleTargets(site); + if (targets.size() != 1) { + System.err.println(targets.size() + " targets found for " + site); + for (Iterator k = targets.iterator(); k.hasNext();) { + System.err.println(" " + k.next()); + } + fail("found " + targets.size() + " targets for " + site + " in " + node); + } + } + } + } + } +} diff --git a/com.ibm.wala.core.tests/com.ibm.wala.core.tests/src/com/ibm/wala/core/tests/callGraph/CompareCDGTest.java b/com.ibm.wala.core.tests/com.ibm.wala.core.tests/src/com/ibm/wala/core/tests/callGraph/CompareCDGTest.java new file mode 100644 index 000000000..4e247de64 --- /dev/null +++ b/com.ibm.wala.core.tests/com.ibm.wala.core.tests/src/com/ibm/wala/core/tests/callGraph/CompareCDGTest.java @@ -0,0 +1,433 @@ +/******************************************************************************* + * Copyright (c) 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.core.tests.callGraph; + +import java.util.Iterator; +import java.util.Set; +import java.util.Vector; + +import com.ibm.wala.cfg.IBasicBlock; +import com.ibm.wala.cfg.cdg.BVControlDependenceGraph; +import com.ibm.wala.cfg.cdg.ControlDependenceGraph; +import com.ibm.wala.core.tests.util.TestConstants; +import com.ibm.wala.core.tests.util.WalaTestCase; +import com.ibm.wala.ecore.java.scope.EJavaAnalysisScope; +import com.ibm.wala.emf.wrappers.EMFScopeWrapper; +import com.ibm.wala.emf.wrappers.JavaScopeUtil; +import com.ibm.wala.ipa.callgraph.AnalysisOptions; +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.CallGraphStats; +import com.ibm.wala.ipa.callgraph.Entrypoints; +import com.ibm.wala.ipa.callgraph.impl.Util; +import com.ibm.wala.ipa.callgraph.propagation.cfa.CFABuilder; +import com.ibm.wala.ipa.cha.ClassHierarchy; +import com.ibm.wala.ipa.cha.ClassHierarchyException; +import com.ibm.wala.shrikeBT.IInstruction; +import com.ibm.wala.ssa.IR; +import com.ibm.wala.ssa.SSACFG; +import com.ibm.wala.ssa.SSAInstruction; +import com.ibm.wala.ssa.SSACFG.BasicBlock; +import com.ibm.wala.types.MethodReference; +import com.ibm.wala.util.debug.Assertions; +import com.ibm.wala.util.debug.Trace; +import com.ibm.wala.util.warnings.WalaException; +import com.ibm.wala.util.warnings.WarningSet; +import com.ibm.wala.viz.DotUtil; + +/** + * @author Mangala Gowri Nanda (minor hacks by Julian Dolby (dolby@us.ibm.com) + * to fit into domo junit test framework) + * + */ +public class CompareCDGTest extends WalaTestCase { + + /** + * Usage: CompareCDGTest + * + * The "jar file name" should be something like "/tmp/testdata/java_cup.jar" + * + * @param args + */ + public static void main(String[] args) { + run(args); + } + + /** + * Usage: args = "-appJar [jar file name] " The "jar file name" should be + * something like "/tmp/testdata/java_cup.jar" + * + * @param args + */ + public static void run(String[] args) { + try { + run(buildCallGraphCommandLine(args[0])); + } catch (WalaException e) { + Trace.println(e); + } + } + + public static void run(CallGraph g) { + compareCDGs(g); + Trace.println(CallGraphStats.getStats(g)); + } + + private static void compareCDGs(CallGraph g) { + long cdgTime = 0; + long bvTime = 0; + String dotExe = "dot"; + for (Iterator it = g.iterateNodes(); it.hasNext();) { + CGNode n = (CGNode) it.next(); + MethodReference mref = n.getMethod().getReference(); + Trace.println(mref.toString()); + // if(app.equals("Application")) + { + IR ir = g.getInterpreter(n).getIR(n, new WarningSet()); + if (ir != null) { + SSACFG cfg = ir.getControlFlowGraph(); + long startTime = System.currentTimeMillis(); + ControlDependenceGraph cdg = new ControlDependenceGraph(cfg, true); + long diff = System.currentTimeMillis() - startTime; + cdgTime += diff; + + startTime = System.currentTimeMillis(); + BVControlDependenceGraph bvcdg = new BVControlDependenceGraph(cfg); + diff = System.currentTimeMillis() - startTime; + bvTime += diff; + + if (!compatible(cfg, cdg, bvcdg)) { + Trace.println("\tMISMATCH!!"); + Vector vec = checkCFG(cfg, mref); + if (vec != null) { + Trace.println(mref + " has " + vec.size() + " blocks with no predecessors"); + } + + Trace.println("\nControlDependenceGraph output::"); + dumpCDGInfo(cfg, cdg); + Trace.println("\nBitVector ControlDependenceGraph output::"); + dumpCDGInfo(cfg, bvcdg); + Trace.println(""); + + String dotFile = "tmp.dot"; + String psFile = mref.getName() + ".cdg.ps"; + try { + DotUtil.dotify(cdg, null, dotFile, psFile, dotExe); + } catch (WalaException e) { + e.printStackTrace(); + } + + psFile = mref.getName() + ".bv.ps"; + try { + DotUtil.dotify(bvcdg, null, dotFile, psFile, dotExe); + } catch (WalaException e) { + e.printStackTrace(); + } + + Assertions.UNREACHABLE(); + } + } + } + } + Trace.println("Time to compute ControlDependenceGraph=" + cdgTime); + Trace.println("Time to compute BVControlDependenceGraph=" + bvTime); + } + + private static boolean compatible(SSACFG cfg, ControlDependenceGraph cdg, BVControlDependenceGraph bv) { + boolean ret = true; + for (Iterator it = cfg.iterateNodes(); it.hasNext();) { + SSACFG.BasicBlock ibb = (SSACFG.BasicBlock) it.next(); + int cCount = cdg.getPredNodeCount(ibb); + int bCount = bv.getPredNodeCount(ibb); + if (cCount != bCount) { + Trace.println("\tPred Count mismatch for " + ibb); + ret = false; + } + Iterator cdit = cdg.getPredNodes(ibb); + while (cdit.hasNext()) { + SSACFG.BasicBlock cdgbb = (SSACFG.BasicBlock) cdit.next(); + if (!bv.hasEdge(cdgbb, ibb)) { + Trace.println("\tPred " + cdgbb + " mismatch for " + ibb); + ret = false; + } + Set clabels = cdg.getEdgeLabels(cdgbb, ibb); + Set blabels = bv.getEdgeLabels(cdgbb, ibb); + Iterator labit = clabels.iterator(); + while (labit.hasNext()) { + Object lab = labit.next(); + if (!blabels.contains(lab)) { + Trace.println("\tLabel " + lab + " missing at " + cdgbb + " --> " + ibb); + ret = false; + } + } + } + + cCount = cdg.getSuccNodeCount(ibb); + bCount = bv.getSuccNodeCount(ibb); + if (cCount != bCount) { + Trace.println("\tSucc Count mismatch for " + ibb); + ret = false; + } + cdit = cdg.getSuccNodes(ibb); + while (cdit.hasNext()) { + SSACFG.BasicBlock cdgbb = (SSACFG.BasicBlock) cdit.next(); + if (!bv.hasEdge(ibb, cdgbb)) { + Trace.println("\tSucc " + cdgbb + " mismatch for " + ibb); + ret = false; + } + Set clabels = cdg.getEdgeLabels(ibb, cdgbb); + Set blabels = bv.getEdgeLabels(ibb, cdgbb); + Iterator labit = clabels.iterator(); + while (labit.hasNext()) { + Object lab = labit.next(); + if (!blabels.contains(lab)) { + Trace.println("\tLabel " + lab + " missing at " + ibb + " --> " + cdgbb); + ret = false; + } + } + } + + } + return ret; + } + + private static void dumpCDGInfo(SSACFG cfg, ControlDependenceGraph cdg) { + Trace.println("{\n"); + Vector seen = new Vector(); + SSACFG.BasicBlock entry = (SSACFG.BasicBlock) cfg.entry(); + Vector worklist = new Vector(); + worklist.add(entry); + while (worklist.size() > 0) { + SSACFG.BasicBlock ibb = worklist.remove(worklist.size() - 1); + if (seen.contains(ibb)) + continue; + seen.add(ibb); + + int number = ibb.getNumber(); + Trace.print("\n\tBB ID:" + number + "::" + ibb + " (CD="); + Iterator cdit = cdg.getPredNodes(ibb); + while (cdit.hasNext()) { + SSACFG.BasicBlock cdgbb = (SSACFG.BasicBlock) cdit.next(); + Trace.print(cdgbb.getNumber() + "["); + Set labels = cdg.getEdgeLabels(cdgbb, ibb); + Iterator labit = labels.iterator(); + while (labit.hasNext()) { + Object lab = labit.next(); + Trace.print(lab + ","); + } + Trace.print("] "); + } + Trace.print(")"); + + Iterator succ = cfg.getSuccNodes(ibb); + Trace.print(" (SUCC="); + while (succ.hasNext()) { + SSACFG.BasicBlock isc = (SSACFG.BasicBlock) succ.next(); + Trace.print(isc.getNumber() + ", "); + worklist.add(isc); + } + Trace.print(")"); + + Iterator pred = cfg.getPredNodes(ibb); + Trace.print(" (PRED="); + while (pred.hasNext()) { + SSACFG.BasicBlock isc = (SSACFG.BasicBlock) pred.next(); + Trace.print(isc.getNumber() + ", "); + } + Trace.println(") {"); + + Iterator it = ibb.iterateAllInstructions(); + int j = 0; + while (it.hasNext()) { + SSAInstruction inst = (SSAInstruction) it.next(); + if (inst != null) { + Trace.println("\t\t" + j++ + ":" + inst.toString()); + } + } + Trace.println("\t}\n"); + } + Trace.println("}\n"); + } + + private static void dumpCDGInfo(SSACFG cfg, BVControlDependenceGraph cdg) { + Trace.println("{\n"); + Vector seen = new Vector(); + SSACFG.BasicBlock entry = (SSACFG.BasicBlock) cfg.entry(); + Vector worklist = new Vector(); + worklist.add(entry); + while (worklist.size() > 0) { + SSACFG.BasicBlock ibb = worklist.remove(worklist.size() - 1); + if (seen.contains(ibb)) + continue; + seen.add(ibb); + + int number = ibb.getNumber(); + Trace.print("\n\tBB ID:" + number + "::" + ibb + " (CD="); + Iterator cdit = cdg.getPredNodes(ibb); + while (cdit.hasNext()) { + SSACFG.BasicBlock cdgbb = (SSACFG.BasicBlock) cdit.next(); + Trace.print(cdgbb.getNumber() + "["); + Set labels = cdg.getEdgeLabels(cdgbb, ibb); + Iterator labit = labels.iterator(); + while (labit.hasNext()) { + Object lab = labit.next(); + Trace.print(lab + ","); + } + Trace.print("] "); + } + Trace.print(")"); + + Iterator succ = cfg.getSuccNodes(ibb); + Trace.print(" (SUCC="); + while (succ.hasNext()) { + SSACFG.BasicBlock isc = (SSACFG.BasicBlock) succ.next(); + Trace.print(isc.getNumber() + ", "); + worklist.add(isc); + } + Trace.print(")"); + + Iterator pred = cfg.getPredNodes(ibb); + Trace.print(" (PRED="); + while (pred.hasNext()) { + SSACFG.BasicBlock isc = (SSACFG.BasicBlock) pred.next(); + Trace.print(isc.getNumber() + ", "); + } + Trace.println(") {"); + + Iterator it = ibb.iterateAllInstructions(); + int j = 0; + while (it.hasNext()) { + SSAInstruction inst = (SSAInstruction) it.next(); + if (inst != null) { + Trace.println("\t\t" + j++ + ":" + inst.toString()); + } + } + Trace.println("\t}\n"); + } + Trace.println("}\n"); + } + + /* + * private static void buildUncheckedCDGs(CallGraph g) { String dotExe = + * "dot"; int count = 0; for (Iterator it = g.iterateNodes(); it.hasNext();) { + * count++; CGNode n = (CGNode) it.next(); MethodReference mref = + * n.getMethod().getReference(); IR ir = ((SSAContextInterpreter) + * g.getInterpreter(n)).getIR(n, new WarningSet()); if (ir != null) { SSACFG + * cfg = ir.getControlFlowGraph(); Vector vec = checkCFG(cfg, mref); if ( vec != + * null ) { // Trace.println(mref.toString()); ControlDependenceGraph cdg = + * new ControlDependenceGraph(cfg,true); boolean found = false; for ( int i=0; + * i0 ) { found = true; break; } } if ( !found ) + * continue; + * + * Trace.println(mref+" has "+vec.size()+ " blocks with no predecessors"); for ( + * int i=0 ; i checkCFG(SSACFG cfg, MethodReference mref) { + Vector vec = new Vector(); + for (Iterator it = cfg.iterateNodes(); it.hasNext();) { + SSACFG.BasicBlock bb = (SSACFG.BasicBlock) it.next(); + if (cfg.getPredNodeCount(bb) == 0) + vec.add(bb); + } + if (vec.size() > 1) { + /* + * Trace.println(mref+" has more than one block with no predecessors"); + * for ( int i=0 ; i callerNodes = HashSetFactory.make(); + callerNodes.addAll(cg.getNodes(thisBinaryRef)); + callerNodes.addAll(cg.getNodes(thatBinaryRef)); + Assertions._assert(callerNodes.size() == 2); + + for (Iterator nodes = callerNodes.iterator(); nodes.hasNext();) { + CGNode n = (CGNode) nodes.next(); + for (Iterator sites = n.iterateSites(); sites.hasNext();) { + CallSiteReference csRef = (CallSiteReference) sites.next(); + if (csRef.getDeclaredTarget().equals(unary2Ref)) { + numberOfCalls++; + Assertions._assert(n.getNumberOfTargets(csRef) == desiredNumberOfTargets); + } + } + } + + Assertions._assert(numberOfCalls == desiredNumberOfCalls); + } + + public void testNoPiNodes() throws ClassHierarchyException { + checkCallAssertions(doGraph(false), 2, 2); + } + + public void testPiNodes() throws ClassHierarchyException { + checkCallAssertions(doGraph(true), 1, 2); + } + +} \ No newline at end of file diff --git a/com.ibm.wala.core.tests/com.ibm.wala.core.tests/src/com/ibm/wala/core/tests/callGraph/ReflectionTest.java b/com.ibm.wala.core.tests/com.ibm.wala.core.tests/src/com/ibm/wala/core/tests/callGraph/ReflectionTest.java new file mode 100644 index 000000000..7ebe2ab44 --- /dev/null +++ b/com.ibm.wala.core.tests/com.ibm.wala.core.tests/src/com/ibm/wala/core/tests/callGraph/ReflectionTest.java @@ -0,0 +1,67 @@ +/******************************************************************************* + * Copyright (c) 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.core.tests.callGraph; + +import java.util.Iterator; + +import com.ibm.wala.core.tests.util.TestConstants; +import com.ibm.wala.core.tests.util.WalaTestCase; +import com.ibm.wala.ecore.java.impl.JavaPackageImpl; +import com.ibm.wala.ipa.callgraph.AnalysisOptions; +import com.ibm.wala.ipa.callgraph.AnalysisScope; +import com.ibm.wala.ipa.callgraph.Entrypoints; +import com.ibm.wala.ipa.cha.ClassHierarchy; +import com.ibm.wala.util.debug.Trace; +import com.ibm.wala.util.warnings.WalaException; +import com.ibm.wala.util.warnings.Warning; +import com.ibm.wala.util.warnings.WarningSet; + +/** + * + * Tests for Call Graph construction + * + * @author sfink + */ + +public class ReflectionTest extends WalaTestCase { + + static { + JavaPackageImpl.init(); + } + + public static void main(String[] args) { + justThisTest(ReflectionTest.class); + } + + public void testReflect1() throws WalaException { + AnalysisScope scope = CallGraphTestUtil.makeJ2SEAnalysisScope(TestConstants.WALA_TESTDATA); + WarningSet warnings = new WarningSet(); + ClassHierarchy cha = ClassHierarchy.make(scope, warnings); + Entrypoints entrypoints = com.ibm.wala.ipa.callgraph.impl.Util.makeMainEntrypoints(scope, cha, TestConstants.REFLECT1_MAIN); + AnalysisOptions options = CallGraphTestUtil.makeAnalysisOptions(scope, entrypoints); + + Trace.println("testReflect1 set up warnings:\n"); + Trace.print(warnings.toString()); + + warnings = CallGraphTest.doCallGraphs(options, cha, scope, null, useShortProfile(), false); + if (warnings.size() > 0) { + System.err.println(warnings); + } + for (Iterator it = warnings.iterator(); it.hasNext(); ) { + Warning w = (Warning)it.next(); + if (w.toString().indexOf("com/ibm/jvm") > 0) { + continue; + } + assertTrue(w.toString(), false); + } + + } +} diff --git a/com.ibm.wala.core.tests/com.ibm.wala.core.tests/src/com/ibm/wala/core/tests/cha/CHATest.java b/com.ibm.wala.core.tests/com.ibm.wala.core.tests/src/com/ibm/wala/core/tests/cha/CHATest.java new file mode 100644 index 000000000..b5e93e0d5 --- /dev/null +++ b/com.ibm.wala.core.tests/com.ibm.wala.core.tests/src/com/ibm/wala/core/tests/cha/CHATest.java @@ -0,0 +1,150 @@ +/******************************************************************************* + * 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.core.tests.cha; + +import java.io.File; +import java.util.Collection; +import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.Properties; + +import org.eclipse.emf.ecore.EObject; + +import com.ibm.wala.classLoader.IClass; +import com.ibm.wala.core.tests.util.TestConstants; +import com.ibm.wala.core.tests.util.WalaTestCase; +import com.ibm.wala.ecore.java.EJavaClass; +import com.ibm.wala.ecore.java.ETypeHierarchy; +import com.ibm.wala.ecore.java.impl.JavaPackageImpl; +import com.ibm.wala.emf.wrappers.EMFBridge; +import com.ibm.wala.emf.wrappers.EMFScopeWrapper; +import com.ibm.wala.emf.wrappers.ETypeHierarchyWrapper; +import com.ibm.wala.emf.wrappers.EUtil; +import com.ibm.wala.ipa.callgraph.AnalysisScope; +import com.ibm.wala.ipa.cha.ClassHierarchy; +import com.ibm.wala.ipa.cha.ClassHierarchyException; +import com.ibm.wala.properties.WalaProperties; +import com.ibm.wala.util.debug.Assertions; +import com.ibm.wala.util.debug.Trace; +import com.ibm.wala.util.warnings.WalaException; +import com.ibm.wala.util.warnings.WarningSet; + +/** + * @author sfink + */ + +public class CHATest extends WalaTestCase { + + static { + JavaPackageImpl.init(); + } + + private static final ClassLoader MY_CLASSLOADER = CHATest.class.getClassLoader(); + + public static void main(String[] args) { + justThisTest(CHATest.class); + } + + public CHATest(String arg0) { + super(arg0); + } + + /** + * regression test with class hierarchy of primordial loader + * @throws ClassHierarchyException + */ + public void testPrimordial() throws ClassHierarchyException { + System.err.println("build ..."); + // build a class hierarchy for the primordial loader + AnalysisScope scope = new EMFScopeWrapper(TestConstants.WALA_TESTDATA, "J2SEClassHierarchyExclusions.xml", MY_CLASSLOADER); + WarningSet warnings = new WarningSet(); + ClassHierarchy cha = ClassHierarchy.make(scope, warnings); + com.ibm.wala.emf.wrappers.ETypeHierarchyWrapper t1 = EMFBridge.makeTypeHierarchy(cha); + System.err.println("save ..."); + // save it to disk + ETypeHierarchy et = (ETypeHierarchy) t1.toEMF(); + Properties p = null;; + try { + p = WalaProperties.loadProperties(); + } catch (WalaException e) { + e.printStackTrace(); + Assertions.UNREACHABLE(); + } + String outputDir = p.getProperty(WalaProperties.OUTPUT_DIR); + String fileName = outputDir + File.separator + "primordialTH.xml"; + Collection persist = new LinkedList(); + persist.add(et); + persist.add(et.getClasses().getNodes()); + persist.add(et.getInterfaces().getNodes()); + try { + EUtil.saveToFile(persist, fileName); + } catch (WalaException e1) { + e1.printStackTrace(); + Assertions.UNREACHABLE("failed to save to file " + fileName + "\n. outputDir was " + outputDir); + } + + System.err.println("read ..."); + // load it back into memory + ETypeHierarchyWrapper et2 = ETypeHierarchyWrapper.loadFromFile(fileName); + System.err.println("check ..."); + // check that they are isomorphic + // TODO: add general utilities for isomorphism + com.ibm.wala.ipa.callgraph.impl.Util.checkGraphSubset(t1.getClasses(), et2.getClasses()); + com.ibm.wala.ipa.callgraph.impl.Util.checkGraphSubset(et2.getClasses(), t1.getClasses()); + com.ibm.wala.ipa.callgraph.impl.Util.checkGraphSubset(t1.getInterfaces(), et2.getInterfaces()); + com.ibm.wala.ipa.callgraph.impl.Util.checkGraphSubset(et2.getInterfaces(), t1.getInterfaces()); + checkInterfaces(cha, et2); + } + + /** + * check that the set of interfaces for each class is consistent between cha + * and T. + * + * @param cha + * @param T + */ + private void checkInterfaces(ClassHierarchy cha, ETypeHierarchyWrapper T) { + try { + for (Iterator it = cha.iterateAllClasses(); it.hasNext();) { + IClass klass = (IClass) it.next(); + if (!klass.isInterface()) { + EJavaClass eKlass = EMFBridge.makeJavaClass(klass.getReference()); + HashSet impls = new HashSet(5); + for (Iterator it2 = klass.getDirectInterfaces().iterator(); it2.hasNext();) { + IClass iface = (IClass) it2.next(); + impls.add(EMFBridge.makeJavaClass(iface.getReference())); + } + Collection c = T.getImplements(eKlass); + checkSetsEqual(impls, c); + } + } + } catch (ClassHierarchyException e) { + e.printStackTrace(); + Assertions.UNREACHABLE(); + } + } + + private void checkSetsEqual(Collection c1, Collection c2) { + if (!c1.containsAll(c2)) { + c2.removeAll(c1); + Trace.printCollection("DIFF: c2 contains but not c1 ", c2); + assertTrue("c1 not superset of c2, see trace file for details", false); + return; + } + if (!c2.containsAll(c1)) { + c1.removeAll(c2); + Trace.printCollection("DIFF: c1 contains but not c2 ", c1); + assertTrue("c2 not superset of c1, see trace file for details", false); + return; + } + } +} diff --git a/com.ibm.wala.core.tests/com.ibm.wala.core.tests/src/com/ibm/wala/core/tests/cha/LibraryVersionTest.java b/com.ibm.wala.core.tests/com.ibm.wala.core.tests/src/com/ibm/wala/core/tests/cha/LibraryVersionTest.java new file mode 100644 index 000000000..c007d3038 --- /dev/null +++ b/com.ibm.wala.core.tests/com.ibm.wala.core.tests/src/com/ibm/wala/core/tests/cha/LibraryVersionTest.java @@ -0,0 +1,37 @@ +/******************************************************************************* + * 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.core.tests.cha; + +import junit.framework.Assert; + +import com.ibm.wala.core.tests.ir.DeterministicIRTest; +import com.ibm.wala.core.tests.util.TestConstants; +import com.ibm.wala.core.tests.util.WalaTestCase; +import com.ibm.wala.emf.wrappers.EMFScopeWrapper; +import com.ibm.wala.ipa.callgraph.AnalysisScope; + +/** + * Test code that attempts to find the library version from + * the analysis scope. + * + * @author JulianDolby (dolby@us.ibm.com) + */ +public class LibraryVersionTest extends WalaTestCase { + + private static final ClassLoader MY_CLASSLOADER = DeterministicIRTest.class.getClassLoader(); + + public void testLibraryVersion() { + AnalysisScope scope = new EMFScopeWrapper(TestConstants.WALA_TESTDATA, "J2SEClassHierarchyExclusions.xml", MY_CLASSLOADER); + System.err.println("java library version is " + scope.getJavaLibraryVersion()); + Assert.assertTrue(scope.isJava15Libraries()||scope.isJava14Libraries()); + } + +} diff --git a/com.ibm.wala.core.tests/com.ibm.wala.core.tests/src/com/ibm/wala/core/tests/cha/SourceMapTest.java b/com.ibm.wala.core.tests/com.ibm.wala.core.tests/src/com/ibm/wala/core/tests/cha/SourceMapTest.java new file mode 100644 index 000000000..4ca6d9d27 --- /dev/null +++ b/com.ibm.wala.core.tests/com.ibm.wala.core.tests/src/com/ibm/wala/core/tests/cha/SourceMapTest.java @@ -0,0 +1,60 @@ +/******************************************************************************* + * 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.core.tests.cha; + +import com.ibm.wala.classLoader.IClass; +import com.ibm.wala.core.tests.util.TestConstants; +import com.ibm.wala.core.tests.util.WalaTestCase; +import com.ibm.wala.emf.wrappers.EMFScopeWrapper; +import com.ibm.wala.ipa.callgraph.AnalysisScope; +import com.ibm.wala.ipa.cha.ClassHierarchy; +import com.ibm.wala.ipa.cha.ClassHierarchyException; +import com.ibm.wala.types.TypeReference; +import com.ibm.wala.util.warnings.WarningSet; + +/** + * A test of support for source file mapping + * + * @author sfink + */ +public class SourceMapTest extends WalaTestCase { + private static final ClassLoader MY_CLASSLOADER = SourceMapTest.class.getClassLoader(); + + private final static String CLASS_IN_PRIMORDIAL_JAR = "Lcom/ibm/wala/model/SyntheticFactory"; + + public void testHello() throws ClassHierarchyException { + AnalysisScope scope = null; + scope = new EMFScopeWrapper(TestConstants.HELLO, null, MY_CLASSLOADER); + // TODO: it's annoying to have to build a class hierarchy here. + // see feature 38676 + ClassHierarchy cha = ClassHierarchy.make(scope, new WarningSet()); + TypeReference t = TypeReference.findOrCreate(scope.getApplicationLoader(), TestConstants.HELLO_MAIN); + IClass klass = cha.lookupClass(t); + assertTrue("failed to load " + t, klass != null); + String sourceFile = klass.getSourceFileName(); + System.err.println("Source file: " + sourceFile); + assertTrue(sourceFile != null); + } + + public void testFromJar() throws ClassHierarchyException { + AnalysisScope scope = null; + scope = new EMFScopeWrapper(TestConstants.HELLO, null, MY_CLASSLOADER); + // TODO: it's annoying to have to build a class hierarchy here. + // open a feature to fix this + ClassHierarchy cha = ClassHierarchy.make(scope, new WarningSet()); + TypeReference t = TypeReference.findOrCreate(scope.getPrimordialLoader(), CLASS_IN_PRIMORDIAL_JAR); + IClass klass = cha.lookupClass(t); + assertTrue(klass != null); + String sourceFile = klass.getSourceFileName(); + assertTrue(sourceFile != null); + System.err.println("Source file: " + sourceFile); + } +} \ No newline at end of file diff --git a/com.ibm.wala.core.tests/com.ibm.wala.core.tests/src/com/ibm/wala/core/tests/ir/CFGTest.java b/com.ibm.wala.core.tests/com.ibm.wala.core.tests/src/com/ibm/wala/core/tests/ir/CFGTest.java new file mode 100644 index 000000000..98cdb8515 --- /dev/null +++ b/com.ibm.wala.core.tests/com.ibm.wala.core.tests/src/com/ibm/wala/core/tests/ir/CFGTest.java @@ -0,0 +1,97 @@ +/******************************************************************************* + * 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.core.tests.ir; + +import com.ibm.wala.cfg.ControlFlowGraph; +import com.ibm.wala.cfg.TwoExitCFG; +import com.ibm.wala.classLoader.IMethod; +import com.ibm.wala.core.tests.util.WalaTestCase; +import com.ibm.wala.ecore.java.scope.EJavaAnalysisScope; +import com.ibm.wala.emf.wrappers.EMFScopeWrapper; +import com.ibm.wala.emf.wrappers.JavaScopeUtil; +import com.ibm.wala.ipa.callgraph.AnalysisOptions; +import com.ibm.wala.ipa.callgraph.impl.Everywhere; +import com.ibm.wala.ipa.cha.ClassHierarchy; +import com.ibm.wala.ssa.IR; +import com.ibm.wala.types.MethodReference; +import com.ibm.wala.util.StringStuff; +import com.ibm.wala.util.debug.Assertions; +import com.ibm.wala.util.debug.Trace; +import com.ibm.wala.util.graph.GraphIntegrity; +import com.ibm.wala.util.graph.GraphIntegrity.UnsoundGraphException; +import com.ibm.wala.util.warnings.WarningSet; + +/** + * Test integrity of CFGs + */ +public class CFGTest extends WalaTestCase { + + public static void main(String[] args) { + justThisTest(CFGTest.class); + } + + /** + * Build an IR, then check integrity on two flavors of CFG + */ + private void doMethod(String methodSig) { + try { + EJavaAnalysisScope escope = JavaScopeUtil.makePrimordialScope(); + + // generate a DOMO-consumable wrapper around the incoming scope object + EMFScopeWrapper scope = EMFScopeWrapper.generateScope(escope); + + // invoke DOMO to build a DOMO class hierarchy object + WarningSet warnings = new WarningSet(); + ClassHierarchy cha = ClassHierarchy.make(scope, warnings); + + MethodReference mr = StringStuff.makeMethodReference(methodSig); + + IMethod m = cha.resolveMethod(mr); + if (m == null) { + Assertions.UNREACHABLE("could not resolve " + mr); + } + AnalysisOptions options = new AnalysisOptions(); + options.getSSAOptions().setUsePiNodes(true); + IR ir = options.getSSACache().findOrCreateIR(m, Everywhere.EVERYWHERE, cha, options.getSSAOptions(), new WarningSet()); + + ControlFlowGraph cfg = ir.getControlFlowGraph(); + try { + GraphIntegrity.check(cfg); + } catch (UnsoundGraphException e) { + e.printStackTrace(); + Trace.println(ir); + assertTrue(" failed cfg integrity check for " + methodSig, false); + } + + cfg = new TwoExitCFG(cfg); + try { + GraphIntegrity.check(cfg); + } catch (UnsoundGraphException e) { + e.printStackTrace(); + Trace.println(ir); + Trace.println(cfg); + assertTrue(" failed 2-exit cfg integrity check for " + methodSig, false); + } + } catch (Exception e) { + e.printStackTrace(); + Assertions.UNREACHABLE(); + } + } + + /** + * this method does not exist in 1.5 libraries public void testFDBigInt() { + * doMethod("java.lang.FDBigInt.class$(Ljava/lang/String;)Ljava/lang/Class;"); } + */ + + public void testResolveProxyClass() { + doMethod("java.io.ObjectInputStream.resolveProxyClass([Ljava/lang/String;)Ljava/lang/Class;"); + } +} diff --git a/com.ibm.wala.core.tests/com.ibm.wala.core.tests/src/com/ibm/wala/core/tests/ir/CornerCasesTest.java b/com.ibm.wala.core.tests/com.ibm.wala.core.tests/src/com/ibm/wala/core/tests/ir/CornerCasesTest.java new file mode 100644 index 000000000..ade83e2ae --- /dev/null +++ b/com.ibm.wala.core.tests/com.ibm.wala.core.tests/src/com/ibm/wala/core/tests/ir/CornerCasesTest.java @@ -0,0 +1,83 @@ +/******************************************************************************* + * 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.core.tests.ir; + +import com.ibm.wala.analysis.typeInference.TypeInference; +import com.ibm.wala.classLoader.IClass; +import com.ibm.wala.classLoader.IMethod; +import com.ibm.wala.classLoader.ShrikeCTMethodWrapper; +import com.ibm.wala.core.tests.util.TestConstants; +import com.ibm.wala.core.tests.util.WalaTestCase; +import com.ibm.wala.emf.wrappers.EMFScopeWrapper; +import com.ibm.wala.ipa.callgraph.AnalysisOptions; +import com.ibm.wala.ipa.callgraph.AnalysisScope; +import com.ibm.wala.ipa.callgraph.impl.Everywhere; +import com.ibm.wala.ipa.cha.ClassHierarchy; +import com.ibm.wala.ipa.cha.ClassHierarchyException; +import com.ibm.wala.ssa.IR; +import com.ibm.wala.types.Descriptor; +import com.ibm.wala.types.Selector; +import com.ibm.wala.types.TypeReference; +import com.ibm.wala.util.Atom; +import com.ibm.wala.util.debug.Trace; +import com.ibm.wala.util.warnings.WarningSet; + +/** + * tests for weird corner cases, such as when the input program doesn't verify + * + * @author sfink + */ +public class CornerCasesTest extends WalaTestCase { + + private static final ClassLoader MY_CLASSLOADER = CornerCasesTest.class.getClassLoader(); + + /** + * test that getMethod() works even if a declared ancester interface doesn't + * exist + * @throws ClassHierarchyException + */ + public void testBug38484() throws ClassHierarchyException { + AnalysisScope scope = null; + scope = new EMFScopeWrapper(TestConstants.WALA_TESTDATA, "J2SEClassHierarchyExclusions.xml", MY_CLASSLOADER); + WarningSet warnings = new WarningSet(); + ClassHierarchy cha = ClassHierarchy.make(scope, warnings); + TypeReference t = TypeReference.findOrCreateClass(scope.getApplicationLoader(), "cornerCases", "YuckyInterface"); + IClass klass = cha.lookupClass(t); + assertTrue(klass != null); + IMethod m = klass.getMethod(new Selector(Atom.findOrCreateAsciiAtom("x"), Descriptor.findOrCreateUTF8("()V"))); + assertTrue(m == null); + Trace.print(warnings.toString()); + } + + /** + * test that type inference works in the presence of a getfield where the + * field's declared type cannot be loaded + * @throws ClassHierarchyException + */ + public void testBug38540() throws ClassHierarchyException { + AnalysisScope scope = null; + scope = new EMFScopeWrapper(TestConstants.WALA_TESTDATA, "J2SEClassHierarchyExclusions.xml", MY_CLASSLOADER); + AnalysisOptions options = new AnalysisOptions(); + WarningSet warnings = new WarningSet(); + ClassHierarchy cha = ClassHierarchy.make(scope, warnings); + TypeReference t = TypeReference.findOrCreateClass(scope.getApplicationLoader(), "cornerCases", "Main"); + IClass klass = cha.lookupClass(t); + assertTrue(klass != null); + ShrikeCTMethodWrapper m = (ShrikeCTMethodWrapper) klass.getMethod(new Selector(Atom.findOrCreateAsciiAtom("foo"), Descriptor + .findOrCreateUTF8("()Ljava/lang/Object;"))); + assertTrue(m != null); + IR ir = options.getIRFactory().makeIR(m, Everywhere.EVERYWHERE, cha, options.getSSAOptions(), warnings); + new TypeInference(ir, cha); + + Trace.print(warnings.toString()); + } + +} diff --git a/com.ibm.wala.core.tests/com.ibm.wala.core.tests/src/com/ibm/wala/core/tests/ir/DeterministicIRTest.java b/com.ibm.wala.core.tests/com.ibm.wala.core.tests/src/com/ibm/wala/core/tests/ir/DeterministicIRTest.java new file mode 100644 index 000000000..9adaf30f5 --- /dev/null +++ b/com.ibm.wala.core.tests/com.ibm.wala.core.tests/src/com/ibm/wala/core/tests/ir/DeterministicIRTest.java @@ -0,0 +1,216 @@ +/******************************************************************************* + * 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.core.tests.ir; + +import java.util.Iterator; + +import com.ibm.wala.classLoader.ClassLoaderFactory; +import com.ibm.wala.classLoader.ClassLoaderFactoryImpl; +import com.ibm.wala.classLoader.IMethod; +import com.ibm.wala.core.tests.util.TestConstants; +import com.ibm.wala.core.tests.util.WalaTestCase; +import com.ibm.wala.emf.wrappers.EMFScopeWrapper; +import com.ibm.wala.ipa.callgraph.AnalysisOptions; +import com.ibm.wala.ipa.callgraph.AnalysisScope; +import com.ibm.wala.ipa.callgraph.impl.Everywhere; +import com.ibm.wala.ipa.cha.ClassHierarchy; +import com.ibm.wala.ipa.cha.ClassHierarchyException; +import com.ibm.wala.ssa.IR; +import com.ibm.wala.ssa.SSAInstruction; +import com.ibm.wala.types.MethodReference; +import com.ibm.wala.util.Atom; +import com.ibm.wala.util.ImmutableByteArray; +import com.ibm.wala.util.UTF8Convert; +import com.ibm.wala.util.graph.GraphIntegrity; +import com.ibm.wala.util.graph.GraphIntegrity.UnsoundGraphException; +import com.ibm.wala.util.warnings.WarningSet; + +/** + * Test that the SSA-numbering of variables in the IR is deterministic. + * + * Introduced 05-AUG-03; the default implementation of hashCode was being + * invoked. Object.hashCode is a source of random numbers and has no place in a + * deterministic program. + */ +public class DeterministicIRTest extends WalaTestCase { + + private static final ClassLoader MY_CLASSLOADER = DeterministicIRTest.class.getClassLoader(); + + private WarningSet warnings; + private AnalysisScope scope; + private ClassHierarchy cha; + private AnalysisOptions options; + + public static void main(String[] args) { + justThisTest(DeterministicIRTest.class); + } + + /* + * (non-Javadoc) + * + * @see junit.framework.TestCase#setUp() + */ + protected void setUp() throws Exception { + + warnings = new WarningSet(); + scope = new EMFScopeWrapper(TestConstants.WALA_TESTDATA, "J2SEClassHierarchyExclusions.xml", MY_CLASSLOADER); + + options = new AnalysisOptions(scope, null); + ClassLoaderFactory factory = new ClassLoaderFactoryImpl(scope.getExclusions(), warnings); + + warnings = new WarningSet(); + + try { + cha = ClassHierarchy.make(scope, factory, warnings); + } catch (ClassHierarchyException e) { + throw new Exception(); + } + } + + /* + * (non-Javadoc) + * + * @see junit.framework.TestCase#tearDown() + */ + protected void tearDown() throws Exception { + warnings = null; + scope = null; + cha = null; + super.tearDown(); + } + + /** + * @param method + */ + private IR doMethod(MethodReference method) { + assertNotNull("method not found", method); + IMethod imethod = cha.resolveMethod(method); + assertNotNull("imethod not found", imethod); + IR ir1 = options.getIRFactory().makeIR(imethod, Everywhere.EVERYWHERE, cha, options.getSSAOptions(), warnings); + options.getSSACache().wipe(); + + checkNotAllNull(ir1.getInstructions()); + checkNoneNull(ir1.iterateAllInstructions()); + try { + GraphIntegrity.check(ir1.getControlFlowGraph()); + } catch (UnsoundGraphException e) { + System.err.println(ir1); + e.printStackTrace(); + assertTrue("unsound CFG for ir1", false); + } + + IR ir2 = options.getIRFactory().makeIR(imethod, Everywhere.EVERYWHERE, cha, options.getSSAOptions(), warnings); + options.getSSACache().wipe(); + + try { + GraphIntegrity.check(ir2.getControlFlowGraph()); + } catch (UnsoundGraphException e1) { + System.err.println(ir2); + e1.printStackTrace(); + assertTrue("unsound CFG for ir2", false); + } + + assertEquals(ir1.toString(), ir2.toString()); + return ir1; + } + + // The Tests /////////////////////////////////////////////////////// + + /** + * @param iterator + */ + private void checkNoneNull(Iterator iterator) { + while (iterator.hasNext()) { + assertTrue(iterator.next() != null); + } + + } + + /** + * @param instructions + */ + private static void checkNotAllNull(SSAInstruction[] instructions) { + for (int i = 0; i < instructions.length; i++) { + if (instructions[i] != null) { + return; + } + } + assertTrue("no instructions generated", false); + } + + public void testIR1() { + // 'remove' is a nice short method + doMethod(scope.findMethod(AnalysisScope.APPLICATION, "Ljava/util/HashMap", Atom.findOrCreateUnicodeAtom("remove"), + new ImmutableByteArray(UTF8Convert.toUTF8("(Ljava/lang/Object;)Ljava/lang/Object;")))); + } + + public void testIR2() { + // 'equals' is a nice medium-sized method + doMethod(scope.findMethod(AnalysisScope.APPLICATION, "Ljava/lang/String", Atom.findOrCreateUnicodeAtom("equals"), + new ImmutableByteArray(UTF8Convert.toUTF8("(Ljava/lang/Object;)Z")))); + } + + public void testIR3() { + // 'resolveProxyClass' is a nice long method (at least in Sun libs) + doMethod(scope.findMethod(AnalysisScope.APPLICATION, "Ljava/io/ObjectInputStream", Atom + .findOrCreateUnicodeAtom("resolveProxyClass"), new ImmutableByteArray(UTF8Convert + .toUTF8("([Ljava/lang/String;)Ljava/lang/Class;")))); + } + + public void testLocalNamesWithoutPiNodes() { + boolean save = options.getSSAOptions().getUsePiNodes(); + options.getSSAOptions().setUsePiNodes( false ); + IR ir = doMethod(scope.findMethod(AnalysisScope.APPLICATION, "LcornerCases/Locals", Atom.findOrCreateUnicodeAtom("foo"), + new ImmutableByteArray(UTF8Convert.toUTF8("([Ljava/lang/String;)V")))); + options.getSSAOptions().setUsePiNodes( save ); + + + // v1 should be the parameter "a" at pc 0 + String[] names = ir.getLocalNames(0,1); + assertTrue("failed local name resolution for v1@0" , names != null); + assertTrue("incorrect number of local names for v1@0: " + names.length , names.length == 1); + assertTrue("incorrect local name resolution for v1@0: " + names[0], names[0].equals("a")); + + // v2 is a compiler-induced temporary + assertTrue("didn't expect name for v2 at pc 2" , ir.getLocalNames(2,2) == null); + + // at pc 5, v1 should represent the locals "a" and "b" + names = ir.getLocalNames(5,1); + assertTrue("failed local name resolution for v1@5" , names != null); + assertTrue("incorrect number of local names for v1@5: " + names.length , names.length == 2); + assertTrue("incorrect local name resolution #0 for v1@5: " + names[0], names[0].equals("a")); + assertTrue("incorrect local name resolution #1 for v1@5: " + names[1], names[1].equals("b")); + } + + public void testLocalNamesWithPiNodes() { + boolean save = options.getSSAOptions().getUsePiNodes(); + options.getSSAOptions().setUsePiNodes( true ); + IR ir = doMethod(scope.findMethod(AnalysisScope.APPLICATION, "LcornerCases/Locals", Atom.findOrCreateUnicodeAtom("foo"), + new ImmutableByteArray(UTF8Convert.toUTF8("([Ljava/lang/String;)V")))); + options.getSSAOptions().setUsePiNodes( save ); + + // v1 should be the parameter "a" at pc 0 + String[] names = ir.getLocalNames(0,1); + assertTrue("failed local name resolution for v1@0" , names != null); + assertTrue("incorrect number of local names for v1@0: " + names.length , names.length == 1); + assertTrue("incorrect local name resolution for v1@0: " + names[0], names[0].equals("a")); + + // v2 is a compiler-induced temporary + assertTrue("didn't expect name for v2 at pc 2" , ir.getLocalNames(2,2) == null); + + // at pc 5, v1 should represent the locals "a" and "b" + names = ir.getLocalNames(5,1); + assertTrue("failed local name resolution for v1@5" , names != null); + assertTrue("incorrect number of local names for v1@5: " + names.length , names.length == 2); + assertTrue("incorrect local name resolution #0 for v1@5: " + names[0], names[0].equals("a")); + assertTrue("incorrect local name resolution #1 for v1@5: " + names[1], names[1].equals("b")); + } +} diff --git a/com.ibm.wala.core.tests/com.ibm.wala.core.tests/src/com/ibm/wala/core/tests/ptrs/MultiDimArrayTest.java b/com.ibm.wala.core.tests/com.ibm.wala.core.tests/src/com/ibm/wala/core/tests/ptrs/MultiDimArrayTest.java new file mode 100644 index 000000000..cb94b715e --- /dev/null +++ b/com.ibm.wala.core.tests/com.ibm.wala.core.tests/src/com/ibm/wala/core/tests/ptrs/MultiDimArrayTest.java @@ -0,0 +1,92 @@ +/******************************************************************************* + * Copyright (c) 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.core.tests.ptrs; + +import java.util.Iterator; + +import com.ibm.wala.core.tests.callGraph.CallGraphTestUtil; +import com.ibm.wala.core.tests.util.TestConstants; +import com.ibm.wala.core.tests.util.WalaTestCase; +import com.ibm.wala.ipa.callgraph.AnalysisOptions; +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.CallGraphBuilder; +import com.ibm.wala.ipa.callgraph.Entrypoints; +import com.ibm.wala.ipa.callgraph.impl.Util; +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.ipa.cha.ClassHierarchy; +import com.ibm.wala.ipa.cha.ClassHierarchyException; +import com.ibm.wala.util.debug.Assertions; +import com.ibm.wala.util.intset.OrdinalSet; +import com.ibm.wala.util.warnings.WarningSet; + +/** + * + * Test for pointer analysis of multidimensional arrays + * + * @author sfink + */ + +public class MultiDimArrayTest extends WalaTestCase { + + + public static void main(String[] args) { + justThisTest(MultiDimArrayTest.class); + } + + /** + * Constructor for SpecJTest. + * + * @param arg0 + */ + public MultiDimArrayTest(String arg0) { + super(arg0); + } + + + public void testMultiDim() throws ClassHierarchyException { + + AnalysisScope scope = CallGraphTestUtil.makeJ2SEAnalysisScope(TestConstants.WALA_TESTDATA); + WarningSet warnings = new WarningSet(); + ClassHierarchy cha = ClassHierarchy.make(scope, warnings); + Entrypoints entrypoints = com.ibm.wala.ipa.callgraph.impl.Util + .makeMainEntrypoints(scope, cha, TestConstants.MULTI_DIM_MAIN); + AnalysisOptions options = CallGraphTestUtil.makeAnalysisOptions(scope, entrypoints); + + CallGraphBuilder builder = Util.makeVanillaZeroOneCFABuilder(options, cha, scope, warnings); + CallGraph cg = builder.makeCallGraph(options); + PointerAnalysis pa = builder.getPointerAnalysis(); + System.err.println(pa); + + CGNode node = findDoNothingNode(cg); + PointerKey pk = pa.getHeapModel().getPointerKeyForLocal(node, 1); + OrdinalSet ptsTo = pa.getPointsToSet(pk); + assertEquals(1, ptsTo.size()); + } + + private final static CGNode findDoNothingNode(CallGraph cg) { + for (Iterator it = cg.iterateNodes(); it.hasNext(); ) { + CGNode n = it.next(); + if (n.getMethod().getName().toString().equals("doNothing")) { + return n; + } + } + Assertions.UNREACHABLE("Unexpected: failed to find doNothing node"); + return null; + } + + + + +} diff --git a/com.ibm.wala.core.tests/com.ibm.wala.core.tests/src/com/ibm/wala/core/tests/slicer/SlicerTest.java b/com.ibm.wala.core.tests/com.ibm.wala.core.tests/src/com/ibm/wala/core/tests/slicer/SlicerTest.java new file mode 100644 index 000000000..9d5db355a --- /dev/null +++ b/com.ibm.wala.core.tests/com.ibm.wala.core.tests/src/com/ibm/wala/core/tests/slicer/SlicerTest.java @@ -0,0 +1,542 @@ +/******************************************************************************* + * Copyright (c) 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.core.tests.slicer; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.PrintWriter; +import java.util.Collection; +import java.util.Iterator; + +import junit.framework.TestCase; + +import com.ibm.wala.core.tests.callGraph.CallGraphTestUtil; +import com.ibm.wala.core.tests.util.TestConstants; +import com.ibm.wala.examples.drivers.GVSlice; +import com.ibm.wala.ipa.callgraph.AnalysisOptions; +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.CallGraphBuilder; +import com.ibm.wala.ipa.callgraph.Entrypoints; +import com.ibm.wala.ipa.callgraph.impl.Util; +import com.ibm.wala.ipa.cha.ClassHierarchy; +import com.ibm.wala.ipa.cha.ClassHierarchyException; +import com.ibm.wala.ipa.slicer.NormalStatement; +import com.ibm.wala.ipa.slicer.Slicer; +import com.ibm.wala.ipa.slicer.Statement; +import com.ibm.wala.ipa.slicer.Slicer.ControlDependenceOptions; +import com.ibm.wala.ipa.slicer.Slicer.DataDependenceOptions; +import com.ibm.wala.ssa.IR; +import com.ibm.wala.ssa.SSAArrayLoadInstruction; +import com.ibm.wala.ssa.SSAConditionalBranchInstruction; +import com.ibm.wala.ssa.SSAGetInstruction; +import com.ibm.wala.ssa.SSAInstruction; +import com.ibm.wala.ssa.SSAInvokeInstruction; +import com.ibm.wala.ssa.SSANewInstruction; +import com.ibm.wala.ssa.SSAPutInstruction; +import com.ibm.wala.types.Descriptor; +import com.ibm.wala.util.Atom; +import com.ibm.wala.util.debug.Assertions; +import com.ibm.wala.util.intset.IntSet; +import com.ibm.wala.util.warnings.WarningSet; + +public class SlicerTest extends TestCase { + + public void testSlice1() throws ClassHierarchyException { + AnalysisScope scope = CallGraphTestUtil.makeJ2SEAnalysisScope(TestConstants.WALA_TESTDATA); + WarningSet warnings = new WarningSet(); + ClassHierarchy cha = ClassHierarchy.make(scope, warnings); + Entrypoints entrypoints = com.ibm.wala.ipa.callgraph.impl.Util.makeMainEntrypoints(scope, cha, TestConstants.SLICE1_MAIN); + AnalysisOptions options = CallGraphTestUtil.makeAnalysisOptions(scope, entrypoints); + + CallGraphBuilder builder = Util.makeZeroOneCFABuilder(options, cha, scope, warnings); + CallGraph cg = builder.makeCallGraph(options); + + CGNode main = findMainMethod(cg); + + Statement s = findCallTo(main, "print"); + System.err.println("Statement: " + s); + // compute a data slice + Collection slice = Slicer.computeBackwardSlice(s, cg, builder.getPointerAnalysis(), DataDependenceOptions.FULL, + ControlDependenceOptions.NONE); + dumpSlice(slice); + assertEquals(18, slice.size()); + } + + public void testSlice2() throws ClassHierarchyException { + AnalysisScope scope = CallGraphTestUtil.makeJ2SEAnalysisScope(TestConstants.WALA_TESTDATA); + WarningSet warnings = new WarningSet(); + ClassHierarchy cha = ClassHierarchy.make(scope, warnings); + Entrypoints entrypoints = com.ibm.wala.ipa.callgraph.impl.Util.makeMainEntrypoints(scope, cha, TestConstants.SLICE2_MAIN); + AnalysisOptions options = CallGraphTestUtil.makeAnalysisOptions(scope, entrypoints); + + CallGraphBuilder builder = Util.makeZeroOneCFABuilder(options, cha, scope, warnings); + CallGraph cg = builder.makeCallGraph(options); + + CGNode main = findMethod(cg, "baz"); + + Statement s = findCallTo(main, "print"); + System.err.println("Statement: " + s); + // compute a data slice + Collection slice = Slicer.computeBackwardSlice(s, cg, builder.getPointerAnalysis(), DataDependenceOptions.FULL, + ControlDependenceOptions.NONE); + dumpSlice(slice); + assertEquals(22, slice.size()); + } + + public void testSlice3() throws ClassHierarchyException { + AnalysisScope scope = CallGraphTestUtil.makeJ2SEAnalysisScope(TestConstants.WALA_TESTDATA); + WarningSet warnings = new WarningSet(); + ClassHierarchy cha = ClassHierarchy.make(scope, warnings); + Entrypoints entrypoints = com.ibm.wala.ipa.callgraph.impl.Util.makeMainEntrypoints(scope, cha, TestConstants.SLICE3_MAIN); + AnalysisOptions options = CallGraphTestUtil.makeAnalysisOptions(scope, entrypoints); + + CallGraphBuilder builder = Util.makeZeroOneCFABuilder(options, cha, scope, warnings); + CallGraph cg = builder.makeCallGraph(options); + + CGNode main = findMethod(cg, "main"); + + Statement s = findCallTo(main, "doNothing"); + System.err.println("Statement: " + s); + // compute a data slice + Collection slice = Slicer.computeBackwardSlice(s, cg, builder.getPointerAnalysis(), DataDependenceOptions.FULL, + ControlDependenceOptions.NONE); + dumpSlice(slice); + assertEquals(1, countAllocations(slice)); + } + + public void testSlice4() throws ClassHierarchyException { + AnalysisScope scope = CallGraphTestUtil.makeJ2SEAnalysisScope(TestConstants.WALA_TESTDATA); + WarningSet warnings = new WarningSet(); + ClassHierarchy cha = ClassHierarchy.make(scope, warnings); + Entrypoints entrypoints = com.ibm.wala.ipa.callgraph.impl.Util.makeMainEntrypoints(scope, cha, TestConstants.SLICE4_MAIN); + AnalysisOptions options = CallGraphTestUtil.makeAnalysisOptions(scope, entrypoints); + + CallGraphBuilder builder = Util.makeZeroOneCFABuilder(options, cha, scope, warnings); + CallGraph cg = builder.makeCallGraph(options); + + CGNode main = findMainMethod(cg); + Statement s = findCallTo(main, "foo"); + s = GVSlice.getReturnStatementForCall(s); + System.err.println("Statement: " + s); + // compute a data slice + Collection slice = Slicer.computeForwardSlice(s, cg, builder.getPointerAnalysis(), DataDependenceOptions.FULL, + ControlDependenceOptions.NONE); + dumpSlice(slice); + assertEquals(4, slice.size()); + } + + public void testSlice5() throws ClassHierarchyException { + AnalysisScope scope = CallGraphTestUtil.makeJ2SEAnalysisScope(TestConstants.WALA_TESTDATA); + WarningSet warnings = new WarningSet(); + ClassHierarchy cha = ClassHierarchy.make(scope, warnings); + Entrypoints entrypoints = com.ibm.wala.ipa.callgraph.impl.Util.makeMainEntrypoints(scope, cha, TestConstants.SLICE5_MAIN); + AnalysisOptions options = CallGraphTestUtil.makeAnalysisOptions(scope, entrypoints); + + CallGraphBuilder builder = Util.makeZeroOneCFABuilder(options, cha, scope, warnings); + CallGraph cg = builder.makeCallGraph(options); + + CGNode n = findMethod(cg, "baz"); + Statement s = findCallTo(n, "foo"); + s = GVSlice.getReturnStatementForCall(s); + System.err.println("Statement: " + s); + // compute a data slice + Collection slice = Slicer.computeForwardSlice(s, cg, builder.getPointerAnalysis(), DataDependenceOptions.FULL, + ControlDependenceOptions.NONE); + dumpSlice(slice); + assertEquals(7, slice.size()); + } + + public void testTestCD1() throws ClassHierarchyException { + AnalysisScope scope = CallGraphTestUtil.makeJ2SEAnalysisScope(TestConstants.WALA_TESTDATA); + WarningSet warnings = new WarningSet(); + ClassHierarchy cha = ClassHierarchy.make(scope, warnings); + Entrypoints entrypoints = com.ibm.wala.ipa.callgraph.impl.Util.makeMainEntrypoints(scope, cha, TestConstants.SLICE_TESTCD1); + AnalysisOptions options = CallGraphTestUtil.makeAnalysisOptions(scope, entrypoints); + + CallGraphBuilder builder = Util.makeZeroOneCFABuilder(options, cha, scope, warnings); + CallGraph cg = builder.makeCallGraph(options); + + CGNode main = findMainMethod(cg); + + Statement s = findCallToDoNothing(main); + System.err.println("Statement: " + s); + // compute a data slice + Collection slice = Slicer.computeBackwardSlice(s, cg, builder.getPointerAnalysis(), DataDependenceOptions.NONE, + ControlDependenceOptions.FULL); + dumpSlice(slice); + assertEquals(2, countConditionals(slice)); + } + + public void testTestCD2() throws ClassHierarchyException { + AnalysisScope scope = CallGraphTestUtil.makeJ2SEAnalysisScope(TestConstants.WALA_TESTDATA); + WarningSet warnings = new WarningSet(); + ClassHierarchy cha = ClassHierarchy.make(scope, warnings); + Entrypoints entrypoints = com.ibm.wala.ipa.callgraph.impl.Util.makeMainEntrypoints(scope, cha, TestConstants.SLICE_TESTCD2); + AnalysisOptions options = CallGraphTestUtil.makeAnalysisOptions(scope, entrypoints); + + CallGraphBuilder builder = Util.makeZeroOneCFABuilder(options, cha, scope, warnings); + CallGraph cg = builder.makeCallGraph(options); + + CGNode main = findMainMethod(cg); + + Statement s = findCallToDoNothing(main); + System.err.println("Statement: " + s); + // compute a data slice + Collection slice = Slicer.computeBackwardSlice(s, cg, builder.getPointerAnalysis(), DataDependenceOptions.NONE, + ControlDependenceOptions.FULL); + dumpSlice(slice); + assertEquals(1, countConditionals(slice)); + } + + public void testTestCD3() throws ClassHierarchyException { + AnalysisScope scope = CallGraphTestUtil.makeJ2SEAnalysisScope(TestConstants.WALA_TESTDATA); + WarningSet warnings = new WarningSet(); + ClassHierarchy cha = ClassHierarchy.make(scope, warnings); + Entrypoints entrypoints = com.ibm.wala.ipa.callgraph.impl.Util.makeMainEntrypoints(scope, cha, TestConstants.SLICE_TESTCD3); + AnalysisOptions options = CallGraphTestUtil.makeAnalysisOptions(scope, entrypoints); + + CallGraphBuilder builder = Util.makeZeroOneCFABuilder(options, cha, scope, warnings); + CallGraph cg = builder.makeCallGraph(options); + + CGNode main = findMainMethod(cg); + + Statement s = findCallToDoNothing(main); + System.err.println("Statement: " + s); + // compute a data slice + Collection slice = Slicer.computeBackwardSlice(s, cg, builder.getPointerAnalysis(), DataDependenceOptions.NONE, + ControlDependenceOptions.FULL); + dumpSlice(slice); + assertEquals(0, countConditionals(slice)); + } + + public void testTestId() throws ClassHierarchyException { + AnalysisScope scope = CallGraphTestUtil.makeJ2SEAnalysisScope(TestConstants.WALA_TESTDATA); + WarningSet warnings = new WarningSet(); + ClassHierarchy cha = ClassHierarchy.make(scope, warnings); + Entrypoints entrypoints = com.ibm.wala.ipa.callgraph.impl.Util.makeMainEntrypoints(scope, cha, TestConstants.SLICE_TESTID); + AnalysisOptions options = CallGraphTestUtil.makeAnalysisOptions(scope, entrypoints); + + CallGraphBuilder builder = Util.makeZeroOneCFABuilder(options, cha, scope, warnings); + CallGraph cg = builder.makeCallGraph(options); + + CGNode main = findMainMethod(cg); + + Statement s = findCallToDoNothing(main); + System.err.println("Statement: " + s); + // compute a data slice + Collection slice = Slicer.computeBackwardSlice(s, cg, builder.getPointerAnalysis(), DataDependenceOptions.FULL, + ControlDependenceOptions.NONE); + dumpSlice(slice); + assertEquals(1, countAllocations(slice)); + } + + public void testTestArrays() throws ClassHierarchyException { + AnalysisScope scope = CallGraphTestUtil.makeJ2SEAnalysisScope(TestConstants.WALA_TESTDATA); + WarningSet warnings = new WarningSet(); + ClassHierarchy cha = ClassHierarchy.make(scope, warnings); + Entrypoints entrypoints = com.ibm.wala.ipa.callgraph.impl.Util.makeMainEntrypoints(scope, cha, TestConstants.SLICE_TESTARRAYS); + AnalysisOptions options = CallGraphTestUtil.makeAnalysisOptions(scope, entrypoints); + + CallGraphBuilder builder = Util.makeZeroOneCFABuilder(options, cha, scope, warnings); + CallGraph cg = builder.makeCallGraph(options); + + CGNode main = findMainMethod(cg); + + Statement s = findCallToDoNothing(main); + System.err.println("Statement: " + s); + // compute a data slice + Collection slice = Slicer.computeBackwardSlice(s, cg, builder.getPointerAnalysis(), DataDependenceOptions.FULL, + ControlDependenceOptions.NONE); + dumpSlice(slice); + assertEquals(2, countAllocations(slice)); + assertEquals(1, countAloads(slice)); + } + + public void testTestFields() throws ClassHierarchyException { + AnalysisScope scope = CallGraphTestUtil.makeJ2SEAnalysisScope(TestConstants.WALA_TESTDATA); + WarningSet warnings = new WarningSet(); + ClassHierarchy cha = ClassHierarchy.make(scope, warnings); + Entrypoints entrypoints = com.ibm.wala.ipa.callgraph.impl.Util.makeMainEntrypoints(scope, cha, TestConstants.SLICE_TESTFIELDS); + AnalysisOptions options = CallGraphTestUtil.makeAnalysisOptions(scope, entrypoints); + + CallGraphBuilder builder = Util.makeZeroOneCFABuilder(options, cha, scope, warnings); + CallGraph cg = builder.makeCallGraph(options); + + CGNode main = findMainMethod(cg); + + Statement s = findCallToDoNothing(main); + System.err.println("Statement: " + s); + // compute a data slice + Collection slice = Slicer.computeBackwardSlice(s, cg, builder.getPointerAnalysis(), DataDependenceOptions.FULL, + ControlDependenceOptions.NONE); + dumpSlice(slice); + assertEquals(2, countAllocations(slice)); + assertEquals(1, countPutfields(slice)); + } + + public void testThin1() throws ClassHierarchyException { + AnalysisScope scope = CallGraphTestUtil.makeJ2SEAnalysisScope(TestConstants.WALA_TESTDATA); + WarningSet warnings = new WarningSet(); + ClassHierarchy cha = ClassHierarchy.make(scope, warnings); + Entrypoints entrypoints = com.ibm.wala.ipa.callgraph.impl.Util.makeMainEntrypoints(scope, cha, TestConstants.SLICE_TESTTHIN1); + AnalysisOptions options = CallGraphTestUtil.makeAnalysisOptions(scope, entrypoints); + + CallGraphBuilder builder = Util.makeZeroOneCFABuilder(options, cha, scope, warnings); + CallGraph cg = builder.makeCallGraph(options); + + CGNode main = findMainMethod(cg); + + Statement s = findCallToDoNothing(main); + System.err.println("Statement: " + s); + + // compute normal data slice + // compute a data slice + Collection slice = Slicer.computeBackwardSlice(s, cg, builder.getPointerAnalysis(), DataDependenceOptions.FULL, + ControlDependenceOptions.NONE); + dumpSlice(slice); + assertEquals(3, countAllocations(slice)); + assertEquals(2, countPutfields(slice)); + + // compute thin slice .. ignore base pointers + slice = Slicer.computeBackwardSlice(s, cg, builder.getPointerAnalysis(), DataDependenceOptions.NO_BASE_PTRS, + ControlDependenceOptions.NONE); + dumpSlice(slice); + assertEquals(2, countAllocations(slice)); + assertEquals(1, countPutfields(slice)); + } + + public void testTestGlobal() throws ClassHierarchyException { + AnalysisScope scope = CallGraphTestUtil.makeJ2SEAnalysisScope(TestConstants.WALA_TESTDATA); + WarningSet warnings = new WarningSet(); + ClassHierarchy cha = ClassHierarchy.make(scope, warnings); + Entrypoints entrypoints = com.ibm.wala.ipa.callgraph.impl.Util.makeMainEntrypoints(scope, cha, TestConstants.SLICE_TESTGLOBAL); + AnalysisOptions options = CallGraphTestUtil.makeAnalysisOptions(scope, entrypoints); + + CallGraphBuilder builder = Util.makeZeroOneCFABuilder(options, cha, scope, warnings); + CallGraph cg = builder.makeCallGraph(options); + + CGNode main = findMainMethod(cg); + + Statement s = findCallToDoNothing(main); + System.err.println("Statement: " + s); + // compute a data slice + Collection slice = Slicer.computeBackwardSlice(s, cg, builder.getPointerAnalysis(), DataDependenceOptions.FULL, + ControlDependenceOptions.NONE); + dumpSlice(slice); + assertEquals(1, countAllocations(slice)); + assertEquals(2, countPutstatics(slice)); + assertEquals(2, countGetstatics(slice)); + } + + public void testTestMultiTarget() throws ClassHierarchyException { + AnalysisScope scope = CallGraphTestUtil.makeJ2SEAnalysisScope(TestConstants.WALA_TESTDATA); + WarningSet warnings = new WarningSet(); + ClassHierarchy cha = ClassHierarchy.make(scope, warnings); + Entrypoints entrypoints = com.ibm.wala.ipa.callgraph.impl.Util.makeMainEntrypoints(scope, cha, + TestConstants.SLICE_TESTMULTITARGET); + AnalysisOptions options = CallGraphTestUtil.makeAnalysisOptions(scope, entrypoints); + + CallGraphBuilder builder = Util.makeZeroOneCFABuilder(options, cha, scope, warnings); + CallGraph cg = builder.makeCallGraph(options); + + CGNode main = findMainMethod(cg); + + Statement s = findCallToDoNothing(main); + System.err.println("Statement: " + s); + // compute a data slice + Collection slice = Slicer.computeBackwardSlice(s, cg, builder.getPointerAnalysis(), DataDependenceOptions.FULL, + ControlDependenceOptions.NONE); + dumpSlice(slice); + assertEquals(2, countAllocations(slice)); + } + + public void testTestRecursion() throws ClassHierarchyException { + AnalysisScope scope = CallGraphTestUtil.makeJ2SEAnalysisScope(TestConstants.WALA_TESTDATA); + WarningSet warnings = new WarningSet(); + ClassHierarchy cha = ClassHierarchy.make(scope, warnings); + Entrypoints entrypoints = com.ibm.wala.ipa.callgraph.impl.Util.makeMainEntrypoints(scope, cha, + TestConstants.SLICE_TESTRECURSION); + AnalysisOptions options = CallGraphTestUtil.makeAnalysisOptions(scope, entrypoints); + + CallGraphBuilder builder = Util.makeZeroOneCFABuilder(options, cha, scope, warnings); + CallGraph cg = builder.makeCallGraph(options); + + CGNode main = findMainMethod(cg); + + Statement s = findCallToDoNothing(main); + System.err.println("Statement: " + s); + + // compute a data slice + Collection slice = Slicer.computeBackwardSlice(s, cg, builder.getPointerAnalysis(), DataDependenceOptions.FULL, + ControlDependenceOptions.NONE); + dumpSlice(slice); + assertEquals(3, countAllocations(slice)); + assertEquals(2, countPutfields(slice)); + } + + private int countAllocations(Collection slice) { + int count = 0; + for (Statement s : slice) { + if (s.getKind().equals(Statement.Kind.NORMAL)) { + NormalStatement ns = (NormalStatement) s; + if (ns.getInstruction() instanceof SSANewInstruction) { + count++; + } + } + } + return count; + } + + private int countAloads(Collection slice) { + int count = 0; + for (Statement s : slice) { + if (s.getKind().equals(Statement.Kind.NORMAL)) { + NormalStatement ns = (NormalStatement) s; + if (ns.getInstruction() instanceof SSAArrayLoadInstruction) { + count++; + } + } + } + return count; + } + + private int countConditionals(Collection slice) { + int count = 0; + for (Statement s : slice) { + if (s.getKind().equals(Statement.Kind.NORMAL)) { + NormalStatement ns = (NormalStatement) s; + if (ns.getInstruction() instanceof SSAConditionalBranchInstruction) { + count++; + } + } + } + return count; + } + + private int countPutfields(Collection slice) { + int count = 0; + for (Statement s : slice) { + if (s.getKind().equals(Statement.Kind.NORMAL)) { + NormalStatement ns = (NormalStatement) s; + if (ns.getInstruction() instanceof SSAPutInstruction) { + SSAPutInstruction p = (SSAPutInstruction) ns.getInstruction(); + if (!p.isStatic()) { + count++; + } + } + } + } + return count; + } + + private int countPutstatics(Collection slice) { + int count = 0; + for (Statement s : slice) { + if (s.getKind().equals(Statement.Kind.NORMAL)) { + NormalStatement ns = (NormalStatement) s; + if (ns.getInstruction() instanceof SSAPutInstruction) { + SSAPutInstruction p = (SSAPutInstruction) ns.getInstruction(); + if (p.isStatic()) { + count++; + } + } + } + } + return count; + } + + private int countGetstatics(Collection slice) { + int count = 0; + for (Statement s : slice) { + if (s.getKind().equals(Statement.Kind.NORMAL)) { + NormalStatement ns = (NormalStatement) s; + if (ns.getInstruction() instanceof SSAGetInstruction) { + SSAGetInstruction p = (SSAGetInstruction) ns.getInstruction(); + if (p.isStatic()) { + count++; + } + } + } + } + return count; + } + + public static void dumpSlice(Collection slice) { + dumpSlice(slice,new PrintWriter(System.err)); + } + + public static void dumpSlice(Collection slice, PrintWriter w) { + w.println("SLICE:\n"); + int i = 1; + for (Statement s : slice) { + String line = (i++) + " " + s; + w.println(line); + w.flush(); + } + } + + public static void dumpSliceToFile(Collection slice, String fileName) throws FileNotFoundException { + File f = new File(fileName); + FileOutputStream fo = new FileOutputStream(f); + PrintWriter w = new PrintWriter(fo); + dumpSlice(slice,w); + } + + public static CGNode findMainMethod(CallGraph cg) { + Descriptor d = Descriptor.findOrCreateUTF8("([Ljava/lang/String;)V"); + Atom name = Atom.findOrCreateUnicodeAtom("main"); + for (Iterator it = cg.getSuccNodes(cg.getFakeRootNode()); it.hasNext();) { + CGNode n = it.next(); + if (n.getMethod().getName().equals(name) && n.getMethod().getDescriptor().equals(d)) { + return n; + } + } + Assertions.UNREACHABLE("failed to find main() method"); + return null; + } + + + public static CGNode findMethod(CallGraph cg, String name) { + Atom a = Atom.findOrCreateUnicodeAtom(name); + for (Iterator it = cg.iterateNodes(); it.hasNext();) { + CGNode n = it.next(); + if (n.getMethod().getName().equals(a)) { + return n; + } + } + System.err.println("call graph " + cg); + Assertions.UNREACHABLE("failed to find method " + name); + return null; + } + + public static Statement findCallTo(CGNode n, String methodName) { + IR ir = n.getCallGraph().getInterpreter(n).getIR(n, new WarningSet()); + for (Iterator it = ir.iterateAllInstructions(); it.hasNext();) { + SSAInstruction s = it.next(); + if (s instanceof SSAInvokeInstruction) { + if (s.toString().indexOf(methodName) > -1) { + IntSet indices = ir.getCallInstructionIndices(((SSAInvokeInstruction) s).getCallSite()); + Assertions.productionAssertion(indices.size()== 1, "expected 1 but got " + indices.size()); + return new NormalStatement(n, indices.intIterator().next()); + } + } + } + Assertions.UNREACHABLE("failed to find call to " + methodName + " in " + n); + return null; + } + + private static Statement findCallToDoNothing(CGNode n) { + return findCallTo(n, "doNothing"); + } +} diff --git a/com.ibm.wala.core.tests/com.ibm.wala.core.tests/src/com/ibm/wala/core/tests/util/TestConstants.java b/com.ibm.wala.core.tests/com.ibm.wala.core.tests/src/com/ibm/wala/core/tests/util/TestConstants.java new file mode 100644 index 000000000..91b58e70b --- /dev/null +++ b/com.ibm.wala.core.tests/com.ibm.wala.core.tests/src/com/ibm/wala/core/tests/util/TestConstants.java @@ -0,0 +1,54 @@ +/******************************************************************************* + * Copyright (c) 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.core.tests.util; + +public interface TestConstants { + + public final static String WALA_TESTDATA = "wala.testdata.xml"; + + public static final String CLASSCONSTANT_MAIN = "LclassConstant/ClassConstant"; + public static final String PI_TEST_MAIN = "Lpi/PiNodeCallGraphTestCase"; + public static final String RECURSE_MAIN = "Lrecurse/NList"; + + public final static String HELLO = "hello.xml"; + public final static String HELLO_MAIN = "Lhello/Hello"; + + public final static String BCEL = "bcel.xml"; + public final static String BCEL_VERIFIER_MAIN = "Lorg/apache/bcel/verifier/Verifier"; + + public final static String JLEX = "JLex.xml"; + public final static String JLEX_MAIN = "LJLex/Main"; + + public final static String JAVA_CUP = "java_cup.xml"; + public final static String JAVA_CUP_MAIN = "Ljava_cup/Main"; + + public final static String MULTI_DIM_MAIN = "LmultiDim/TestMultiDim"; + + public final static String REFLECT1_MAIN = "Lreflection/Reflect1"; + + public final static String SLICE1_MAIN = "Lslice/Slice1"; + public final static String SLICE2_MAIN = "Lslice/Slice2"; + public final static String SLICE3_MAIN = "Lslice/Slice3"; + public final static String SLICE4_MAIN = "Lslice/Slice4"; + public final static String SLICE5_MAIN = "Lslice/Slice5"; + public final static String SLICE_TESTCD1 = "Lslice/TestCD1"; + public final static String SLICE_TESTCD2 = "Lslice/TestCD2"; + public final static String SLICE_TESTCD3 = "Lslice/TestCD3"; + public final static String SLICE_TESTID = "Lslice/TestId"; + public final static String SLICE_TESTARRAYS = "Lslice/TestArrays"; + public final static String SLICE_TESTFIELDS = "Lslice/TestFields"; + public final static String SLICE_TESTGLOBAL = "Lslice/TestGlobal"; + public final static String SLICE_TESTMULTITARGET = "Lslice/TestMultiTarget"; + public final static String SLICE_TESTRECURSION = "Lslice/TestRecursion"; + public final static String SLICE_TESTTHIN1 = "Lslice/TestThin1"; + + +} diff --git a/com.ibm.wala.core.tests/com.ibm.wala.core.tests/src/com/ibm/wala/core/tests/util/WalaTestCase.java b/com.ibm.wala.core.tests/com.ibm.wala.core.tests/src/com/ibm/wala/core/tests/util/WalaTestCase.java new file mode 100644 index 000000000..94d6891f2 --- /dev/null +++ b/com.ibm.wala.core.tests/com.ibm.wala.core.tests/src/com/ibm/wala/core/tests/util/WalaTestCase.java @@ -0,0 +1,100 @@ +/******************************************************************************* + * 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.core.tests.util; + +import junit.framework.TestCase; +import junit.framework.TestSuite; + +import com.ibm.wala.util.debug.Trace; +import com.ibm.wala.util.heapTrace.HeapTracer; + +/** + * + * Simple extension to JUnit test case. + * + * @author sfink + */ +public abstract class WalaTestCase extends TestCase { + + final private static boolean ANALYZE_LEAKS = false; + + public static boolean useShortProfile() { + String profile = System.getProperty("com.ibm.wala.junit.profile", "long"); + if (profile.equals("short")) { + return true; + } else { + return false; + } + } + + private String baseTraceFile; + + /* + * (non-Javadoc) + * + * @see junit.framework.TestCase#setUp() + */ + protected void setUp() throws Exception { + baseTraceFile = Trace.getTraceFile(); + if (baseTraceFile != null) { + Trace.setTraceFile(baseTraceFile + "." + getName()); + } + } + + /* + * (non-Javadoc) + * + * @see junit.framework.TestCase#tearDown() + */ + protected void tearDown() throws Exception { + if (baseTraceFile != null) { + Trace.setTraceFile(baseTraceFile); + } + if (ANALYZE_LEAKS) { + HeapTracer.analyzeLeaks(); + } + } + + public WalaTestCase() { + super("DomoTestCase"); + } + + /** + * Utility function: each DetoxTestCase subclass can have a main() method that + * calls this, to create a test suite consisting of just this test. Useful + * when investigating a single failing test. + */ + protected static void justThisTest(Class testClass) { + TestSuite suite = new TestSuite(testClass.getName()); + suite.addTestSuite(testClass); + junit.textui.TestRunner.run(suite); + } + + /** + * @param arg0 + */ + public WalaTestCase(String arg0) { + super(arg0); + } + + protected static void assertBound(String tag, double quantity, double bound) { + String msg = tag + ", quantity: " + quantity + ", bound:" + bound; + Trace.println(msg); + assertTrue(msg, quantity <= bound); + } + + protected static void assertBound(String tag, int quantity, int bound) { + String msg = tag + ", quantity: " + quantity + ", bound:" + bound; + Trace.println(msg); + assertTrue(msg, quantity <= bound); + } + +} diff --git a/com.ibm.wala.core.tests/com.ibm.wala.core.tests/src/com/ibm/wala/examples/analysis/SimpleThreadEscapeAnalysis.java b/com.ibm.wala.core.tests/com.ibm.wala.core.tests/src/com/ibm/wala/examples/analysis/SimpleThreadEscapeAnalysis.java new file mode 100644 index 000000000..1e1fc7aa9 --- /dev/null +++ b/com.ibm.wala.core.tests/com.ibm.wala.core.tests/src/com/ibm/wala/examples/analysis/SimpleThreadEscapeAnalysis.java @@ -0,0 +1,299 @@ +/******************************************************************************* + * Copyright (c) 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.examples.analysis; + +import com.ibm.wala.classLoader.*; +import com.ibm.wala.client.impl.*; +import com.ibm.wala.ipa.callgraph.*; +import com.ibm.wala.ipa.callgraph.impl.*; +import com.ibm.wala.ipa.callgraph.propagation.*; +import com.ibm.wala.ipa.cha.*; +import com.ibm.wala.types.*; +import com.ibm.wala.util.collections.HashSetFactory; +import com.ibm.wala.util.intset.*; + +import java.io.*; +import java.util.*; +import java.util.jar.*; + +/** + *

      + * A simple thread-level escape analysis: this code computes the set of classes + * of which some instance may be accessed by some thread other than the one that + * created it. + *

      + * + *

      + * The algorithm is not very bright; it is based on the observation that there + * are only three ways for an object to pass from one thread to another. + *

        + *
      • The object is stored into a static variable. + *
      • The object is stored into an instance field of a Thread + *
      • The object is reachable from a field of another escaping object. + *
      + *

      + * + *

      + * This observation is implemented in the obvious way: + *

        + *
      1. All static fields are collected + *
      2. All Thread constructor parameters are collected + *
      3. The points-to sets of these values represent the base set of escapees. + *
      4. All object reachable from fields of these objects are added + *
      5. This process continues until a fixpoint is reached + *
      6. The abstract objects in the points-to sets are converted to types + *
      7. This set of types is returned + *

      + * + * @author Julian Dolby + */ +public class SimpleThreadEscapeAnalysis extends AbstractAnalysisEngine { + private final Set applicationJarFiles; + + private final String applicationMainClass; + + /** + * The two input parameters define the program to analyze: the jars of .class + * files and the main class to start from. + */ + public SimpleThreadEscapeAnalysis(Set applicationJarFiles, String applicationMainClass) { + this.applicationJarFiles = applicationJarFiles; + this.applicationMainClass = applicationMainClass; + } + + /** + * Given a root path, add it to the set if it is a jar, or traverse it + * recursively if it is a directory. + */ + private void collectJars(File f, Set result) throws IOException { + if (f.isDirectory()) { + File[] files = f.listFiles(); + for (int i = 0; i < files.length; i++) { + collectJars(files[i], result); + } + } else if (f.getAbsolutePath().endsWith(".jar")) { + result.add(new JarFile(f)); + } + } + + /** + * Collect the set of JarFiles that constitute the system libraries of the + * running JRE. + */ + private JarFile[] getSystemJars() throws IOException { + Set jarFiles = HashSetFactory.make(); + + String javaHomePath = System.getProperty("java.home"); + + if (!javaHomePath.endsWith(File.separator)) { + javaHomePath = javaHomePath + File.separator; + } + + collectJars(new File(javaHomePath + "lib"), jarFiles); + + return jarFiles.toArray(new JarFile[jarFiles.size()]); + } + + /** + * Take the given set of JarFiles that constitute the program, and return a + * set of Module files as expected by the WALA machinery. + */ + private Set getModuleFiles() { + Set result = HashSetFactory.make(); + for (Iterator jars = applicationJarFiles.iterator(); jars.hasNext();) { + result.add(new JarFileModule(jars.next())); + } + + return result; + } + + /** + * The heart of the analysis. + */ + public Set gatherThreadEscapingClasses() throws IOException, ClassHierarchyException { + + // + // set the application to analyze + // + setModuleFiles(getModuleFiles()); + + // + // set the system jar files to use. + // change this if you want to use a specific jre version + // + setJ2SELibraries(getSystemJars()); + + // + // the application and libraries are set, now build the scope... + // + buildAnalysisScope(); + + // + // ...and the class hierarchy + // + ClassHierarchy cha = buildClassHierarchy(); + setClassHierarchy(cha); + + // + // select the call graph construction algorithm + // change this if greater precision is desired + // (see com.ibm.wala.client.impl.*BuilderFactory) + // + setCallGraphBuilderFactory(new ZeroCFABuilderFactory()); + + // + // entrypoints are where analysis starts + // + Entrypoints roots = Util.makeMainEntrypoints(getScope(), cha, applicationMainClass); + + // + // analysis options controls aspects of call graph construction + // + AnalysisOptions options = getDefaultOptions(roots); + + // + // build the call graph + // + buildCallGraph(cha, options, true); + + // + // extract data for analysis + // + CallGraph cg = getCallGraph(); + PointerAnalysis pa = getPointerAnalysis(); + + // + // collect all places where objects can escape their creating thread: + // 1) all static fields + // 2) arguments to Thread constructors + // + Set escapeAnalysisRoots = HashSetFactory.make(); + HeapModel heapModel = pa.getHeapModel(); + + // 1) static fields + for (Iterator clss = cha.iterateAllClasses(); clss.hasNext();) { + IClass cls = (IClass) clss.next(); + Collection staticFields = cls.getDeclaredStaticFields(); + for (Iterator sfs = staticFields.iterator(); sfs.hasNext();) { + IField sf = (IField) sfs.next(); + if (sf.getFieldTypeReference().isReferenceType()) { + escapeAnalysisRoots.add(heapModel.getPointerKeyForStaticField(sf)); + } + } + } + + // 2) instance fields of Threads + // (we hack this by getting the 'this' parameter of all ctor calls; + // this works because the next phase will add all objects transitively + // reachable from fields of types in these pointer keys, and all + // Thread objects must be constructed somewhere) + Collection threads = cha.computeSubClasses(TypeReference.JavaLangThread); + for (Iteratorclss = threads.iterator(); clss.hasNext();) { + IClass cls = (IClass) clss.next(); + for (Iterator ms = cls.getDeclaredMethods(); ms.hasNext();) { + IMethod m = (IMethod) ms.next(); + if (m.isInit()) { + Set nodes = cg.getNodes(m.getReference()); + for (Iterator ns = nodes.iterator(); ns.hasNext();) { + CGNode n = (CGNode) ns.next(); + escapeAnalysisRoots.add(heapModel.getPointerKeyForLocal(n, 1)); + } + } + } + } + + // + // compute escaping types: all types flowing to escaping roots and + // all types transitively reachable through their fields. + // + Set escapingInstanceKeys = HashSetFactory.make(); + + // + // pass 1: get abstract objects (instance keys) for escaping locations + // + for (Iterator rts = escapeAnalysisRoots.iterator(); rts.hasNext();) { + PointerKey root = rts.next(); + OrdinalSet objects = pa.getPointsToSet(root); + for (Iterator objs = objects.iterator(); objs.hasNext();) { + InstanceKey obj = (InstanceKey) objs.next(); + escapingInstanceKeys.add(obj); + } + } + + // + // passes 2+: get fields of escaping keys, and add pointed-to keys + // + Set newKeys = HashSetFactory.make(); + do { + newKeys.clear(); + for (Iterator keys = escapingInstanceKeys.iterator(); keys.hasNext();) { + InstanceKey key = keys.next(); + IClass type = key.getConcreteType(); + if (type.isReferenceType()) { + if (type.isArrayClass()) { + if (((ArrayClass) type).getElementClass() != null) { + PointerKey fk = heapModel.getPointerKeyForArrayContents(key); + OrdinalSet fobjects = pa.getPointsToSet(fk); + for (Iterator fobjs = fobjects.iterator(); fobjs.hasNext();) { + InstanceKey fobj = (InstanceKey) fobjs.next(); + if (!escapingInstanceKeys.contains(fobj)) { + newKeys.add(fobj); + } + } + } + } else { + Collection fields = type.getAllInstanceFields(); + for (Iterator fs = fields.iterator(); fs.hasNext();) { + IField f = (IField) fs.next(); + if (f.getFieldTypeReference().isReferenceType()) { + PointerKey fk = heapModel.getPointerKeyForInstanceField(key, f); + OrdinalSet fobjects = pa.getPointsToSet(fk); + for (Iterator fobjs = fobjects.iterator(); fobjs.hasNext();) { + InstanceKey fobj = (InstanceKey) fobjs.next(); + if (!escapingInstanceKeys.contains(fobj)) { + newKeys.add(fobj); + } + } + } + } + } + } + } + escapingInstanceKeys.addAll(newKeys); + } while (!newKeys.isEmpty()); + + // + // get set of types from set of instance keys + // + Set escapingTypes = HashSetFactory.make(); + for (Iterator keys = escapingInstanceKeys.iterator(); keys.hasNext();) { + InstanceKey key = keys.next(); + escapingTypes.add(key.getConcreteType()); + } + + return escapingTypes; + } + + public static void main(String[] args) throws IOException, ClassHierarchyException { + String mainClassName = args[0]; + + Set jars = HashSetFactory.make(); + for (int i = 1; i < args.length; i++) { + jars.add(new JarFile(args[i])); + } + + Set escapingTypes = (new SimpleThreadEscapeAnalysis(jars, mainClassName)).gatherThreadEscapingClasses(); + + for (Iterator types = escapingTypes.iterator(); types.hasNext();) { + System.out.println(types.next().getName().toString()); + } + } +} diff --git a/com.ibm.wala.core.tests/com.ibm.wala.core.tests/src/com/ibm/wala/examples/drivers/ExportCallGraphToXML.java b/com.ibm.wala.core.tests/com.ibm.wala.core.tests/src/com/ibm/wala/examples/drivers/ExportCallGraphToXML.java new file mode 100644 index 000000000..245ce812d --- /dev/null +++ b/com.ibm.wala.core.tests/com.ibm.wala.core.tests/src/com/ibm/wala/examples/drivers/ExportCallGraphToXML.java @@ -0,0 +1,225 @@ +/******************************************************************************* + * 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.examples.drivers; + +import java.io.File; +import java.util.Collection; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Properties; + +import org.eclipse.emf.ecore.EObject; + +import com.ibm.wala.ecore.java.ECallSite; +import com.ibm.wala.ecore.java.EJavaClass; +import com.ibm.wala.ecore.java.EJavaMethod; +import com.ibm.wala.ecore.java.callGraph.ECallGraph; +import com.ibm.wala.ecore.java.scope.EJavaAnalysisScope; +import com.ibm.wala.emf.wrappers.EMFBridge; +import com.ibm.wala.emf.wrappers.EMFScopeWrapper; +import com.ibm.wala.emf.wrappers.EObjectDictionary; +import com.ibm.wala.emf.wrappers.EObjectGraph; +import com.ibm.wala.emf.wrappers.EObjectGraphImpl; +import com.ibm.wala.emf.wrappers.EUtil; +import com.ibm.wala.emf.wrappers.JavaScopeUtil; +import com.ibm.wala.ipa.callgraph.AnalysisOptions; +import com.ibm.wala.ipa.callgraph.CallGraph; +import com.ibm.wala.ipa.callgraph.Entrypoints; +import com.ibm.wala.ipa.callgraph.impl.Util; +import com.ibm.wala.ipa.cha.ClassHierarchy; +import com.ibm.wala.properties.WalaProperties; +import com.ibm.wala.util.collections.Iterator2Collection; +import com.ibm.wala.util.debug.Assertions; +import com.ibm.wala.util.warnings.WalaException; +import com.ibm.wala.util.warnings.WarningSet; + +/** + * This simple example application builds a call graph writes it to an XML file + * + * @author sfink + */ +public class ExportCallGraphToXML { + + /** + * Usage: ExportCallGraphToXML -appJar [jar file name] The "jar file name" + * should be something like "c:/temp/testdata/java_cup.jar" + * + * @param args + */ + public static void main(String[] args) { + run(args); + } + + /** + * Usage: args = "-appJar [jar file name] " The "jar file name" should be + * something like "c:/temp/testdata/java_cup.jar" + * + * @param args + */ + public static void run(String[] args) { + validateCommandLine(args); + run(args[1]); + } + + /** + * @param appJar + * something like "c:/temp/testdata/java_cup.jar" + */ + public static void run(String appJar) { + try { + + EJavaAnalysisScope escope = JavaScopeUtil.makeAnalysisScope(appJar); + + // generate a DOMO-consumable wrapper around the incoming scope object + EMFScopeWrapper scope = EMFScopeWrapper.generateScope(escope); + + // TODO: return the warning set (need a CAPA type) + // invoke DOMO to build a DOMO class hierarchy object + WarningSet warnings = new WarningSet(); + System.err.println("Build class hierarchy..."); + ClassHierarchy cha = ClassHierarchy.make(scope, warnings); + + Entrypoints entrypoints = com.ibm.wala.ipa.callgraph.impl.Util.makeMainEntrypoints(scope, cha); + AnalysisOptions options = new AnalysisOptions(scope, entrypoints); + + // // + // build the call graph + // // + System.err.println("Build callgraph..."); + com.ibm.wala.ipa.callgraph.CallGraphBuilder builder = Util.makeZeroCFABuilder(options, cha, scope, warnings, null, null); + CallGraph cg = builder.makeCallGraph(options); + + System.err.println("Convert to EMF..."); + com.ibm.wala.emf.wrappers.ECallGraphWrapper ccg = EMFBridge.makeCallGraph(cg); + ECallGraph ecg = (ECallGraph) ccg.export(); + + Properties p = null; + ; + try { + p = WalaProperties.loadProperties(); + } catch (WalaException e) { + e.printStackTrace(); + Assertions.UNREACHABLE(); + } + String filename = p.getProperty(WalaProperties.OUTPUT_DIR) + File.separatorChar + "cg.xml"; + System.err.println("Writing to file: " + filename); + write(ecg, filename); + + // try and load it too + + List l = EUtil.readEObjects(filename, ExportCallGraphToXML.class.getClassLoader()); + + // convert it to a default graph for kicks + ECallGraph output = (ECallGraph) l.get(0); + System.err.println(output.getClass()); + EObjectGraph graph = EObjectGraphImpl.fromEMF(output); + System.err.println("read " + graph.getNumberOfNodes() + " nodes"); + + } catch (WalaException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + + @SuppressWarnings("unchecked") + private static void write(ECallGraph cg, String filename) throws WalaException { + + // make sure every java method reachable from the call graph + // is a node is the call graph + Collection c = new Iterator2Collection(cg.getNodes().getContents().iterator()); + for (Iterator it = c.iterator(); it.hasNext();) { + Object node = it.next(); + if (node instanceof ECallSite) { + ECallSite site = (ECallSite) node; + EJavaMethod method = site.getDeclaredTarget(); + if (!c.contains(method)) { + cg.getNodes().getContents().add(method); + } + + method = site.getJavaMethod(); + if (!c.contains(method)) { + cg.getNodes().getContents().add(method); + } + } + } + + // make a canonical dictionary of all method nodes + EObjectDictionary methodNodes = new EObjectDictionary(); + for (Iterator it = cg.getNodes().getContents().iterator(); it.hasNext();) { + Object node = it.next(); + if (node instanceof EJavaMethod) { + EJavaMethod method = (EJavaMethod) node; + methodNodes.findOrAdd(method); + } + } + + // Create a collection of EObjects to persist + Collection persist = new LinkedList(); + // Persist the call graph itself + persist.add(cg); + // Persist the nodes of the call graph which are NOT contained in the + // ECallGraph + persist.add(cg.getNodes()); + + // Persist all Java classes reachable from the call graph, + // and make sure pointers are canonical + EObjectDictionary klasses = new EObjectDictionary(); + for (Iterator it = cg.getNodes().getContents().iterator(); it.hasNext();) { + Object node = it.next(); + if (node instanceof ECallSite) { + ECallSite site = (ECallSite) node; + EJavaMethod method = (EJavaMethod) site.getDeclaredTarget(); + method = (EJavaMethod) methodNodes.findOrAdd(method); + site.setDeclaredTarget(method); + EJavaClass klass = (EJavaClass) klasses.findOrAdd(method.getJavaClass()); + method.setJavaClass(klass); + + method = site.getJavaMethod(); + method = (EJavaMethod) methodNodes.findOrAdd(method); + site.setJavaMethod(method); + klass = (EJavaClass) klasses.findOrAdd(method.getJavaClass()); + method.setJavaClass(klass); + } else if (node instanceof EJavaMethod) { + EJavaMethod method = (EJavaMethod) node; + EJavaClass klass = (EJavaClass) klasses.findOrAdd(method.getJavaClass()); + method.setJavaClass(klass); + } else { + Assertions.UNREACHABLE("Unexpected type " + node.getClass()); + } + } + persist.add(klasses.export(true)); + + // Save everything to a file. + EUtil.saveToFile(persist, filename); + } + + /** + * Validate that the command-line arguments obey the expected usage. + * + * Usage: + *
        + *
      • args[0] : "-appJar" + *
      • args[1] : something like "c:/temp/testdata/java_cup.jar" g = GVTypeHierarchy.typeHierarchy2Graph(th); + g = GVTypeHierarchy.pruneForAppLoader(g); + if (g.getNumberOfNodes() == 0) { + System.err.println("ERROR: The type hierarchy in " + ExportTypeHierarchyToXML.getFileName() + " has no nodes from the Application loader"); + System.err.println("Probably something's wrong with the input jars being analyzed."); + System.err.println("check the files in the path: " + classpath); + System.err.println("Also look at these warning messages:"); + System.err.println(warnings.toString()); + System.exit(-1); + } + + } catch (WalaException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + + private static void write(ETypeHierarchy t, String filename) throws WalaException { + + if (filename == null) { + throw new WalaException("internal error: null filename parameter"); + } + + // Create a collection of EObjects to persist + Collection persist = new LinkedList(); + // Persist the type hierarchy itself + persist.add(t); + // Persist the classes as well, which are NOT contained in the ETypeHierarchy + persist.add(t.getClasses().getNodes()); + // Persist the interfaces as well, which are NOT contained in the ETypeHierarchy + persist.add(t.getInterfaces().getNodes()); + + // Save everything to a file. + EUtil.saveToFile(persist, filename); + } + + static String getFileName() throws WalaException { + Properties p = null;; + try { + p = WalaProperties.loadProperties(); + } catch (WalaException e) { + e.printStackTrace(); + Assertions.UNREACHABLE(); + } + String file = p.getProperty(WalaProperties.OUTPUT_DIR) + File.separatorChar + FILENAME; + return file; + } + + public static ETypeHierarchy buildTypeHierarchy(String classpath, WarningSet warnings) throws WalaException { + EJavaAnalysisScope escope = JavaScopeUtil.makeAnalysisScope(classpath); + + // generate a WALA-consumable wrapper around the incoming scope object + EMFScopeWrapper scope = EMFScopeWrapper.generateScope(escope); + + // invoke WALA to build a class hierarchy + ClassHierarchy cha = ClassHierarchy.make(scope, warnings); + + // Export the class hierarchy object to an EMF TypeHierarchy object + com.ibm.wala.emf.wrappers.ETypeHierarchyWrapper t1 = EMFBridge.makeTypeHierarchy(cha); + + ETypeHierarchy th = (ETypeHierarchy) t1.toEMF(); + return th; + } + + /** + * Validate that the command-line arguments obey the expected usage. + * + * Usage: args[0] : "-classpath" args[1] : String, a ";"-delimited class path + * + * @param args + * @throws UnsupportedOperationException + * if command-line is malformed. + */ + static void validateCommandLine(String[] args) { + if (args.length < 2) { + throw new UnsupportedOperationException("must have at least 2 command-line arguments"); + } + if (!args[0].equals("-classpath")) { + throw new UnsupportedOperationException("invalid command-line, args[0] should be -classpath, but is " + args[0]); + } + } +} \ No newline at end of file diff --git a/com.ibm.wala.core.tests/com.ibm.wala.core.tests/src/com/ibm/wala/examples/drivers/GVCallGraph.java b/com.ibm.wala.core.tests/com.ibm.wala.core.tests/src/com/ibm/wala/examples/drivers/GVCallGraph.java new file mode 100644 index 000000000..43d420e18 --- /dev/null +++ b/com.ibm.wala.core.tests/com.ibm.wala.core.tests/src/com/ibm/wala/examples/drivers/GVCallGraph.java @@ -0,0 +1,186 @@ +/******************************************************************************* + * 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.examples.drivers; + +import java.io.File; +import java.util.Properties; + +import com.ibm.wala.ecore.java.scope.EJavaAnalysisScope; +import com.ibm.wala.emf.wrappers.EMFScopeWrapper; +import com.ibm.wala.emf.wrappers.JavaScopeUtil; +import com.ibm.wala.examples.properties.WalaExamplesProperties; +import com.ibm.wala.ipa.callgraph.AnalysisOptions; +import com.ibm.wala.ipa.callgraph.CGNode; +import com.ibm.wala.ipa.callgraph.CallGraph; +import com.ibm.wala.ipa.callgraph.Entrypoints; +import com.ibm.wala.ipa.callgraph.impl.Util; +import com.ibm.wala.ipa.callgraph.propagation.LocalPointerKey; +import com.ibm.wala.ipa.cha.ClassHierarchy; +import com.ibm.wala.properties.WalaProperties; +import com.ibm.wala.types.ClassLoaderReference; +import com.ibm.wala.util.collections.Filter; +import com.ibm.wala.util.debug.Assertions; +import com.ibm.wala.util.graph.Graph; +import com.ibm.wala.util.io.CommandLine; +import com.ibm.wala.util.warnings.WalaException; +import com.ibm.wala.util.warnings.WarningSet; +import com.ibm.wala.viz.DotUtil; +import com.ibm.wala.viz.GVUtil; + +/** + * + * This simple example WALA application builds a call graph and fires off + * ghostview to viz a DOT representation. + * + * @author sfink + */ +public class GVCallGraph { + + private final static String PS_FILE = "cg.ps"; + + /** + * Usage: GVCallGraph -appJar [jar file name] The "jar file name" should + * be something like "c:/temp/testdata/java_cup.jar" + * + * @param args + */ + public static void main(String[] args) { + run(args); + } + + /** + * Usage: args = "-appJar [jar file name] " The "jar file name" should be + * something like "c:/temp/testdata/java_cup.jar" + * + * @param args + */ + public static Process run(String[] args) { + Properties p = CommandLine.parse(args); + validateCommandLine(p); + return run(p.getProperty("appJar")); + } + + /** + * @param appJar + * something like "c:/temp/testdata/java_cup.jar" + */ + public static Process run(String appJar) { + try { + + Graph g = buildPrunedCallGraph(appJar); + + Properties p = null; + try { + p = WalaExamplesProperties.loadProperties(); + p.putAll(WalaProperties.loadProperties()); + } catch (WalaException e) { + e.printStackTrace(); + Assertions.UNREACHABLE(); + } + String psFile = p.getProperty(WalaProperties.OUTPUT_DIR) + File.separatorChar + PS_FILE; + + String dotExe = p.getProperty(WalaExamplesProperties.DOT_EXE); + DotUtil.dotify(g, null, GVTypeHierarchy.DOT_FILE, psFile, dotExe); + + String gvExe = p.getProperty(WalaExamplesProperties.GHOSTVIEW_EXE); + return GVUtil.launchGV(psFile, gvExe); + + } catch (WalaException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + return null; + } + } + + /** + * @param appJar + * something like "c:/temp/testdata/java_cup.jar" + * @return a call graph + * @throws WalaException + */ + public static Graph buildPrunedCallGraph(String appJar) throws WalaException { + EJavaAnalysisScope escope = JavaScopeUtil.makeAnalysisScope(appJar); + + // generate a DOMO-consumable wrapper around the incoming scope object + EMFScopeWrapper scope = EMFScopeWrapper.generateScope(escope); + + + // TODO: return the warning set (need a CAPA type) + // invoke DOMO to build a DOMO class hierarchy object + WarningSet warnings = new WarningSet(); + ClassHierarchy cha = ClassHierarchy.make(scope, warnings); + + Entrypoints entrypoints = com.ibm.wala.ipa.callgraph.impl.Util.makeMainEntrypoints(scope, cha); + AnalysisOptions options = new AnalysisOptions(scope, entrypoints); + + // // + // build the call graph + // // + com.ibm.wala.ipa.callgraph.CallGraphBuilder builder = Util.makeZeroCFABuilder(options, cha, scope, warnings, null, null); + CallGraph cg = builder.makeCallGraph(options); + + Graph g = pruneForAppLoader(cg); + return g; + } + + static Graph pruneForAppLoader(CallGraph g) throws WalaException { + return GVTypeHierarchy.pruneGraph(g, new ApplicationLoaderFilter()); + } + + /** + * Validate that the command-line arguments obey the expected usage. + * + * Usage: + *
          + *
        • args[0] : "-appJar" + *
        • args[1] : something like "c:/temp/testdata/java_cup.jar" + *
        • CGNode + *
        • LocalPointerKey + *
        + */ + private static class ApplicationLoaderFilter implements Filter { + + /* + * (non-Javadoc) + * + * @see com.ibm.capa.util.collections.Filter#accepts(java.lang.Object) + */ + public boolean accepts(Object o) { + if (o instanceof CGNode) { + CGNode n = (CGNode) o; + return n.getMethod().getDeclaringClass().getClassLoader().getReference().equals(ClassLoaderReference.Application); + } else if (o instanceof LocalPointerKey) { + LocalPointerKey l = (LocalPointerKey) o; + return accepts(l.getNode()); + } else { + return false; + } + } + + } +} \ No newline at end of file diff --git a/com.ibm.wala.core.tests/com.ibm.wala.core.tests/src/com/ibm/wala/examples/drivers/GVControlDependenceGraph.java b/com.ibm.wala.core.tests/com.ibm.wala.core.tests/src/com/ibm/wala/examples/drivers/GVControlDependenceGraph.java new file mode 100644 index 000000000..967d1bb80 --- /dev/null +++ b/com.ibm.wala.core.tests/com.ibm.wala.core.tests/src/com/ibm/wala/examples/drivers/GVControlDependenceGraph.java @@ -0,0 +1,159 @@ +/******************************************************************************* + * 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.examples.drivers; + +import java.io.File; +import java.util.Properties; + +import com.ibm.wala.cfg.cdg.ControlDependenceGraph; +import com.ibm.wala.classLoader.IMethod; +import com.ibm.wala.ecore.java.scope.EJavaAnalysisScope; +import com.ibm.wala.emf.wrappers.EMFScopeWrapper; +import com.ibm.wala.emf.wrappers.JavaScopeUtil; +import com.ibm.wala.examples.properties.WalaExamplesProperties; +import com.ibm.wala.ipa.callgraph.AnalysisOptions; +import com.ibm.wala.ipa.callgraph.impl.Everywhere; +import com.ibm.wala.ipa.cha.ClassHierarchy; +import com.ibm.wala.properties.WalaProperties; +import com.ibm.wala.ssa.IR; +import com.ibm.wala.types.MethodReference; +import com.ibm.wala.util.StringStuff; +import com.ibm.wala.util.debug.Assertions; +import com.ibm.wala.util.warnings.WalaException; +import com.ibm.wala.util.warnings.WarningSet; +import com.ibm.wala.viz.DotUtil; +import com.ibm.wala.viz.GVUtil; +import com.ibm.wala.viz.GhostviewUtil; + +/** + * + * This simple example application builds a WALA CDG and fires off ghostview + * to viz a DOT representation. + * + * @author sfink + */ +public class GVControlDependenceGraph { + + final public static boolean SANITIZE_CFG = false; + + final public static String PS_FILE = "cdg.ps"; + + /** + * Usage: GVControlDependenceGraph -appJar [jar file name] -sig [method signature] The "jar + * file name" should be something like "c:/temp/testdata/java_cup.jar" The + * signature should be something like "java_cup.lexer.advance()V" + * + * @param args + */ + public static void main(String[] args) { + + run(args); + } + + /** + * @param args + * -appJar [jar file name] -sig [method signature] The "jar file + * name" should be something like "c:/temp/testdata/java_cup.jar" The + * signature should be something like "java_cup.lexer.advance()V" + */ + public static Process run(String[] args) { + validateCommandLine(args); + return run(args[1], args[3]); + } + + /** + * @param appJar + * should be something like "c:/temp/testdata/java_cup.jar" + * @param methodSig + * should be something like "java_cup.lexer.advance()V" + */ + public static Process run(String appJar, String methodSig) { + try { + if (SWTCallGraph.isDirectory(appJar)) { + appJar = SWTCallGraph.findJarFiles(new String[] { appJar }); + } + EJavaAnalysisScope escope = JavaScopeUtil.makeAnalysisScope(appJar); + + // generate a DOMO-consumable wrapper around the incoming scope object + EMFScopeWrapper scope = EMFScopeWrapper.generateScope(escope); + + // invoke DOMO to build a DOMO class hierarchy object + WarningSet warnings = new WarningSet(); + ClassHierarchy cha = ClassHierarchy.make(scope, warnings); + + MethodReference mr = StringStuff.makeMethodReference(methodSig); + + IMethod m = cha.resolveMethod(mr); + if (m == null) { + Assertions.UNREACHABLE("could not resolve " + mr); + } + AnalysisOptions options = new AnalysisOptions(); + options.getSSAOptions().setUsePiNodes(true); + IR ir = options.getSSACache().findOrCreateIR(m, Everywhere.EVERYWHERE, cha, options.getSSAOptions(), new WarningSet()); + + if (ir == null) { + Assertions.UNREACHABLE("Null IR for " + m); + } + + System.err.println(ir.toString()); + ControlDependenceGraph cdg = new ControlDependenceGraph(ir.getControlFlowGraph()); + + Properties wp = null; + try { + wp = WalaProperties.loadProperties(); + wp.putAll(WalaExamplesProperties.loadProperties()); + } catch (WalaException e) { + e.printStackTrace(); + Assertions.UNREACHABLE(); + } + String psFile = wp.getProperty(WalaProperties.OUTPUT_DIR) + File.separatorChar + GVControlDependenceGraph.PS_FILE; + String dotFile = wp.getProperty(WalaProperties.OUTPUT_DIR) + File.separatorChar + + GVTypeHierarchy.DOT_FILE; + String dotExe = wp.getProperty(WalaExamplesProperties.DOT_EXE); + String gvExe = wp.getProperty(WalaExamplesProperties.GHOSTVIEW_EXE); + + DotUtil.dotify(cdg, GhostviewUtil.makeIRDecorator(ir), dotFile, psFile, dotExe); + + return GVUtil.launchGV(psFile, gvExe); + + } catch (WalaException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + return null; + } + } + + /** + * Validate that the command-line arguments obey the expected usage. + * + * Usage: + *
          + *
        • args[0] : "-appJar" + *
        • args[1] : something like "c:/temp/testdata/java_cup.jar" + *
        • args[2] : "-sig" + *
        • args[3] : a method signature like "java_cup.lexer.advance()V" g = pruneSDG(sdg); + DotUtil.dotify(g, makeNodeDecorator(), GVTypeHierarchy.DOT_FILE, psFile, dotExe); + + String gvExe = p.getProperty(WalaExamplesProperties.GHOSTVIEW_EXE); + return GVUtil.launchGV(psFile, gvExe); + + } catch (WalaException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + return null; + } + } + + private static Graph pruneSDG(SDG sdg) { + Filter f = new Filter() { + public boolean accepts(Object o) { + Statement s = (Statement)o; + if (s.getNode().equals(s.getNode().getCallGraph().getFakeRootNode())) { + return false; + } else { + return true; + } + } + }; + return GraphSlicer.prune(sdg, f); + } + + private static NodeDecorator makeNodeDecorator() { + return new NodeDecorator() { + public String getLabel(Object o) throws WalaException { + Statement s = (Statement) o; + switch (s.getKind()) { + case HEAP_PARAM_CALLEE: + case HEAP_PARAM_CALLER: + case HEAP_RET_CALLEE: + case HEAP_RET_CALLER: + HeapStatement h =(HeapStatement)s; + return s.getKind() + "\\n" + h.getNode() + "\\n" + h.getLocation(); + case EXC_RET_CALLEE: + case EXC_RET_CALLER: + case NORMAL: + case NORMAL_RET_CALLEE: + case NORMAL_RET_CALLER: + case PARAM_CALLEE: + case PARAM_CALLER: + case PHI: + default: + return s.toString(); + } + } + + }; + } + + /** + * Validate that the command-line arguments obey the expected usage. + * + * Usage: + *
            + *
          • args[0] : "-appJar" + *
          • args[1] : something like "c:/temp/testdata/java_cup.jar" + *
          • args[2] : "-mainClass" + *
          • args[3] : something like "Lslice/TestRecursion" + * + * @throws UnsupportedOperationException + * if command-line is malformed. + */ + static void validateCommandLine(Properties p) { + if (p.get("appJar") == null) { + throw new UnsupportedOperationException("expected command-line to include -appJar"); + } + if (p.get("mainClass") == null) { + throw new UnsupportedOperationException("expected command-line to include -appJar"); + } + } +} \ No newline at end of file diff --git a/com.ibm.wala.core.tests/com.ibm.wala.core.tests/src/com/ibm/wala/examples/drivers/GVSlice.java b/com.ibm.wala.core.tests/com.ibm.wala.core.tests/src/com/ibm/wala/examples/drivers/GVSlice.java new file mode 100644 index 000000000..bfb231727 --- /dev/null +++ b/com.ibm.wala.core.tests/com.ibm.wala.core.tests/src/com/ibm/wala/examples/drivers/GVSlice.java @@ -0,0 +1,259 @@ +/******************************************************************************* + * 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.examples.drivers; + +import java.io.File; +import java.util.Collection; +import java.util.Properties; + +import com.ibm.wala.core.tests.callGraph.CallGraphTestUtil; +import com.ibm.wala.core.tests.slicer.SlicerTest; +import com.ibm.wala.ecore.java.scope.EJavaAnalysisScope; +import com.ibm.wala.emf.wrappers.EMFScopeWrapper; +import com.ibm.wala.emf.wrappers.JavaScopeUtil; +import com.ibm.wala.examples.properties.WalaExamplesProperties; +import com.ibm.wala.ipa.callgraph.AnalysisOptions; +import com.ibm.wala.ipa.callgraph.CGNode; +import com.ibm.wala.ipa.callgraph.CallGraph; +import com.ibm.wala.ipa.callgraph.CallGraphBuilder; +import com.ibm.wala.ipa.callgraph.Entrypoints; +import com.ibm.wala.ipa.callgraph.impl.Util; +import com.ibm.wala.ipa.cha.ClassHierarchy; +import com.ibm.wala.ipa.slicer.HeapStatement; +import com.ibm.wala.ipa.slicer.NormalStatement; +import com.ibm.wala.ipa.slicer.ParamStatement; +import com.ibm.wala.ipa.slicer.SDG; +import com.ibm.wala.ipa.slicer.Slicer; +import com.ibm.wala.ipa.slicer.Statement; +import com.ibm.wala.ipa.slicer.ParamStatement.CallStatementCarrier; +import com.ibm.wala.ipa.slicer.ParamStatement.ValueNumberCarrier; +import com.ibm.wala.ipa.slicer.Slicer.ControlDependenceOptions; +import com.ibm.wala.ipa.slicer.Slicer.DataDependenceOptions; +import com.ibm.wala.ipa.slicer.Statement.Kind; +import com.ibm.wala.properties.WalaProperties; +import com.ibm.wala.ssa.SSAInstruction; +import com.ibm.wala.ssa.SSAInvokeInstruction; +import com.ibm.wala.util.collections.Filter; +import com.ibm.wala.util.debug.Assertions; +import com.ibm.wala.util.graph.Graph; +import com.ibm.wala.util.graph.GraphIntegrity; +import com.ibm.wala.util.graph.GraphSlicer; +import com.ibm.wala.util.graph.NodeDecorator; +import com.ibm.wala.util.graph.GraphIntegrity.UnsoundGraphException; +import com.ibm.wala.util.io.CommandLine; +import com.ibm.wala.util.warnings.WalaException; +import com.ibm.wala.util.warnings.WarningSet; +import com.ibm.wala.viz.DotUtil; +import com.ibm.wala.viz.GVUtil; + +/** + * + * This simple example WALA application builds an SDG and fires off ghostview to + * viz a DOT representation of a slice in the SDG + * + * @author sfink + */ +public class GVSlice { + + private final static String PS_FILE = "slice.ps"; + + /** + * Usage: GVSDG -appJar [jar file name] -mainclass [main class] -src [method + * name] + * + * The "jar file name" should be something like + * "c:/temp/testdata/java_cup.jar" + * + * @param args + */ + public static void main(String[] args) { + run(args); + } + + /** + */ + public static Process run(String[] args) { + Properties p = CommandLine.parse(args); + validateCommandLine(p); + return run(p.getProperty("appJar"), p.getProperty("mainClass"), p.getProperty("srcCaller"), p.getProperty("srcCallee"), + goBackward(p), GVSDG.getDataDependenceOptions(p), GVSDG.getControlDependenceOptions(p)); + } + + private static boolean goBackward(Properties p) { + return !p.getProperty("dir","backward").equals("forward"); + } + + /** + */ + public static Process run(String appJar, String mainClass, String srcCaller, String srcCallee, boolean goBackward, DataDependenceOptions dOptions, + ControlDependenceOptions cOptions) { + try { + EJavaAnalysisScope escope = JavaScopeUtil.makeAnalysisScope(appJar); + + // generate a WALA-consumable wrapper around the incoming scope object + EMFScopeWrapper scope = EMFScopeWrapper.generateScope(escope); + WarningSet warnings = new WarningSet(); + ClassHierarchy cha = ClassHierarchy.make(scope, warnings); + Entrypoints entrypoints = com.ibm.wala.ipa.callgraph.impl.Util.makeMainEntrypoints(scope, cha, mainClass); + AnalysisOptions options = CallGraphTestUtil.makeAnalysisOptions(scope, entrypoints); + + CallGraphBuilder builder = Util.makeZeroOneCFABuilder(options, cha, scope, warnings); + CallGraph cg = builder.makeCallGraph(options); + SDG sdg = new SDG(cg, builder.getPointerAnalysis(), dOptions, cOptions); + + CGNode main = SlicerTest.findMethod(cg, srcCaller); + Statement s = SlicerTest.findCallTo(main, srcCallee); + System.err.println("Statement: " + s); + Collection slice = null; + if (goBackward) { + slice = Slicer.computeBackwardSlice(s, cg, builder.getPointerAnalysis(), dOptions, cOptions); + } else { + // for forward slices ... we actually slice from the return value of calls. + s = getReturnStatementForCall(s); + slice = Slicer.computeForwardSlice(s, cg, builder.getPointerAnalysis(), dOptions, cOptions); + } + SlicerTest.dumpSlice(slice); + + Graph g = pruneSDG(sdg, slice); + try { + GraphIntegrity.check(g); + } catch (UnsoundGraphException e1) { + e1.printStackTrace(); + Assertions.UNREACHABLE(); + } + Assertions.productionAssertion(g.getNumberOfNodes() == slice.size(), "panic " + g.getNumberOfNodes() + " " + slice.size()); + + Properties p = null; + try { + p = WalaExamplesProperties.loadProperties(); + p.putAll(WalaProperties.loadProperties()); + } catch (WalaException e) { + e.printStackTrace(); + Assertions.UNREACHABLE(); + } + String psFile = p.getProperty(WalaProperties.OUTPUT_DIR) + File.separatorChar + PS_FILE; + + String dotExe = p.getProperty(WalaExamplesProperties.DOT_EXE); + + DotUtil.dotify(g, makeNodeDecorator(), GVTypeHierarchy.DOT_FILE, psFile, dotExe); + + String gvExe = p.getProperty(WalaExamplesProperties.GHOSTVIEW_EXE); + return GVUtil.launchGV(psFile, gvExe); + + } catch (WalaException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + return null; + } + } + + /** + * If s is a call statement, return the statement representing the normal return from s + */ + public static Statement getReturnStatementForCall(Statement s) { + if (s.getKind() == Kind.NORMAL) { + SSAInstruction st = ((NormalStatement)s).getInstruction(); + if (st instanceof SSAInvokeInstruction) { + return new ParamStatement.NormalReturnCaller(s.getNode(),(SSAInvokeInstruction)st); + } else { + return s; + } + } else { + return s; + } + } + + public static Graph pruneSDG(SDG sdg, final Collection slice) { + Filter f = new Filter() { + public boolean accepts(Object o) { + return slice.contains(o); + } + }; + return GraphSlicer.prune(sdg, f); + } + + public static NodeDecorator makeNodeDecorator() { + return new NodeDecorator() { + public String getLabel(Object o) throws WalaException { + Statement s = (Statement) o; + switch (s.getKind()) { + case HEAP_PARAM_CALLEE: + case HEAP_PARAM_CALLER: + case HEAP_RET_CALLEE: + case HEAP_RET_CALLER: + HeapStatement h = (HeapStatement) s; + return s.getKind() + "\\n" + h.getNode() + "\\n" + h.getLocation(); + case NORMAL: + NormalStatement n = (NormalStatement) s; + return n.getNode() + "\\n" + n.getInstruction(); + case PARAM_CALLEE: + case PARAM_CALLER: + if (s instanceof ValueNumberCarrier) { + ValueNumberCarrier vc = (ValueNumberCarrier) s; + if (s instanceof CallStatementCarrier) { + CallStatementCarrier cc = (CallStatementCarrier) s; + return s.getKind() + "\\n" + s.getNode() + "\\n" + cc.getCall() + "\\nv" + vc.getValueNumber(); + } else { + return s.getKind() + "\\n" + s.getNode() + "\\nv" + vc.getValueNumber(); + } + } else { + if (s instanceof CallStatementCarrier) { + CallStatementCarrier cc = (CallStatementCarrier) s; + return s.getKind() + "\\n" + s.getNode() + "\\n" + cc.getCall(); + } else { + return s.toString(); + } + } + case EXC_RET_CALLEE: + case EXC_RET_CALLER: + case NORMAL_RET_CALLEE: + case NORMAL_RET_CALLER: + case PHI: + default: + return s.toString(); + } + } + + }; + } + + /** + * Validate that the command-line arguments obey the expected usage. + * + * Usage: + *
              + *
            • args[0] : "-appJar" + *
            • args[1] : something like "c:/temp/testdata/java_cup.jar" + *
            • args[2] : "-mainClass" + *
            • args[3] : something like "Lslice/TestRecursion" * + *
            • args[4] : "-srcCallee" + *
            • args[5] : something like "print" * + *
            • args[4] : "-srcCaller" + *
            • args[5] : something like "main" + * + * @throws UnsupportedOperationException + * if command-line is malformed. + */ + static void validateCommandLine(Properties p) { + if (p.get("appJar") == null) { + throw new UnsupportedOperationException("expected command-line to include -appJar"); + } + if (p.get("mainClass") == null) { + throw new UnsupportedOperationException("expected command-line to include -mainClass"); + } + if (p.get("srcCallee") == null) { + throw new UnsupportedOperationException("expected command-line to include -srcCallee"); + } + if (p.get("srcCaller") == null) { + throw new UnsupportedOperationException("expected command-line to include -srcCaller"); + } + } +} \ No newline at end of file diff --git a/com.ibm.wala.core.tests/com.ibm.wala.core.tests/src/com/ibm/wala/examples/drivers/GVTypeHierarchy.java b/com.ibm.wala.core.tests/com.ibm.wala.core.tests/src/com/ibm/wala/examples/drivers/GVTypeHierarchy.java new file mode 100644 index 000000000..7583f6330 --- /dev/null +++ b/com.ibm.wala.core.tests/com.ibm.wala.core.tests/src/com/ibm/wala/examples/drivers/GVTypeHierarchy.java @@ -0,0 +1,156 @@ +/******************************************************************************* + * 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.examples.drivers; + +import java.io.File; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; +import java.util.Properties; + +import org.eclipse.emf.ecore.EObject; + +import com.ibm.wala.ecore.java.EClassLoaderName; +import com.ibm.wala.ecore.java.EJavaClass; +import com.ibm.wala.ecore.java.ETypeHierarchy; +import com.ibm.wala.emf.wrappers.EObjectGraphImpl; +import com.ibm.wala.emf.wrappers.ETypeHierarchyWrapper; +import com.ibm.wala.emf.wrappers.EUtil; +import com.ibm.wala.examples.properties.WalaExamplesProperties; +import com.ibm.wala.properties.WalaProperties; +import com.ibm.wala.util.CollectionFilter; +import com.ibm.wala.util.collections.Filter; +import com.ibm.wala.util.debug.Assertions; +import com.ibm.wala.util.graph.Graph; +import com.ibm.wala.util.graph.GraphSlicer; +import com.ibm.wala.util.warnings.WalaException; +import com.ibm.wala.util.warnings.WarningSet; +import com.ibm.wala.viz.DotUtil; +import com.ibm.wala.viz.GVUtil; + +/** + * + * This simple example WALA application builds a TypeHierarchy and fires off + * ghostview to viz a DOT representation. + * + * @author sfink + */ +public class GVTypeHierarchy { + + public final static String DOT_FILE = "temp.dt"; + + private final static String PS_FILE = "th.ps"; + + public static Properties p; + + static { + try { + p = WalaProperties.loadProperties(); + p.putAll(WalaExamplesProperties.loadProperties()); + } catch (WalaException e) { + e.printStackTrace(); + Assertions.UNREACHABLE(); + } + + } + + public static void main(String[] args) { + run(args, false); + } + + public static Process run(String[] args, boolean readFromFile) { + try { + ETypeHierarchy th = null; + if (readFromFile) { + th = readTypeHierarchy(); + } else { + ExportTypeHierarchyToXML.validateCommandLine(args); + String classpath = args[ExportTypeHierarchyToXML.CLASSPATH_INDEX]; + th = ExportTypeHierarchyToXML.buildTypeHierarchy(classpath, new WarningSet()); + } + + Graph g = typeHierarchy2Graph(th); + + g = pruneForAppLoader(g); + String dotFile = p.getProperty(WalaProperties.OUTPUT_DIR) + File.separatorChar + DOT_FILE; + String psFile = p.getProperty(WalaProperties.OUTPUT_DIR) + File.separatorChar + PS_FILE; + String dotExe = p.getProperty(WalaExamplesProperties.DOT_EXE); + String gvExe = p.getProperty(WalaExamplesProperties.GHOSTVIEW_EXE); + DotUtil.dotify(g, null, dotFile, psFile, dotExe); + return GVUtil.launchGV(psFile, gvExe); + + } catch (WalaException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + return null; + } + } + + /* + * (non-Javadoc) + * + * @see com.ibm.capa.core.EAnalysisEngine#processImpl() + */ + public static Graph typeHierarchy2Graph(ETypeHierarchy et) throws WalaException { + ETypeHierarchyWrapper t = new ETypeHierarchyWrapper(et); + EObjectGraphImpl dg = new EObjectGraphImpl(); + for (Iterator it = t.getClasses().iterateNodes(); it.hasNext();) { + dg.addNode(it.next()); + } + for (Iterator it = t.getInterfaces().iterateNodes(); it.hasNext();) { + dg.addNode(it.next()); + } + for (Iterator it = t.getClasses().iterateNodes(); it.hasNext();) { + EJavaClass x = (EJavaClass) it.next(); + for (Iterator it2 = t.getClasses().getSuccNodes(x); it2.hasNext();) { + dg.addEdge(x, it2.next()); + } + for (Iterator it2 = t.getImplements(x).iterator(); it2.hasNext();) { + dg.addEdge(it2.next(), x); + } + } + for (Iterator it = t.getInterfaces().iterateNodes(); it.hasNext();) { + EJavaClass x = (EJavaClass) it.next(); + for (Iterator it2 = t.getInterfaces().getSuccNodes(x); it2.hasNext();) { + dg.addEdge(x, it2.next()); + } + } + + return dg; + } + + static Graph pruneForAppLoader(Graph g) throws WalaException { + Filter f = new Filter() { + public boolean accepts(Object o) { + if (o instanceof EJavaClass) { + EJavaClass klass = (EJavaClass) o; + return (klass.getLoader().equals(EClassLoaderName.APPLICATION_LITERAL)); + } else { + return false; + } + } + }; + + return pruneGraph(g, f); + } + + public static Graph pruneGraph(Graph g, Filter f) throws WalaException { + + Collection slice = GraphSlicer.slice(g, f); + return GraphSlicer.prune(g, new CollectionFilter(slice)); + } + + static ETypeHierarchy readTypeHierarchy() throws WalaException { + + List l = EUtil.readEObjects(ExportTypeHierarchyToXML.getFileName(), ExportTypeHierarchyToXML.class.getClassLoader()); + return (ETypeHierarchy) l.get(0); + } +} \ No newline at end of file diff --git a/com.ibm.wala.core.tests/com.ibm.wala.core.tests/src/com/ibm/wala/examples/drivers/GVWalaIR.java b/com.ibm.wala.core.tests/com.ibm.wala.core.tests/src/com/ibm/wala/examples/drivers/GVWalaIR.java new file mode 100644 index 000000000..ee6be019d --- /dev/null +++ b/com.ibm.wala.core.tests/com.ibm.wala.core.tests/src/com/ibm/wala/examples/drivers/GVWalaIR.java @@ -0,0 +1,152 @@ +/******************************************************************************* + * 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.examples.drivers; + +import java.io.File; +import java.util.Properties; + +import com.ibm.wala.classLoader.IMethod; +import com.ibm.wala.ecore.java.scope.EJavaAnalysisScope; +import com.ibm.wala.emf.wrappers.EMFScopeWrapper; +import com.ibm.wala.emf.wrappers.JavaScopeUtil; +import com.ibm.wala.examples.properties.WalaExamplesProperties; +import com.ibm.wala.ipa.callgraph.AnalysisOptions; +import com.ibm.wala.ipa.callgraph.impl.Everywhere; +import com.ibm.wala.ipa.cha.ClassHierarchy; +import com.ibm.wala.properties.WalaProperties; +import com.ibm.wala.ssa.IR; +import com.ibm.wala.types.MethodReference; +import com.ibm.wala.util.StringStuff; +import com.ibm.wala.util.debug.Assertions; +import com.ibm.wala.util.warnings.WalaException; +import com.ibm.wala.util.warnings.WarningSet; +import com.ibm.wala.viz.GhostviewUtil; + +/** + * + * This simple example application builds a WALA IR and fires off ghostview + * to viz a DOT representation. + * + * @author sfink + */ +public class GVWalaIR { + + final public static boolean SANITIZE_CFG = false; + + final public static String PS_FILE = "ir.ps"; + + /** + * Usage: GVWalaIR -appJar [jar file name] -sig [method signature] The "jar + * file name" should be something like "c:/temp/testdata/java_cup.jar" The + * signature should be something like "java_cup.lexer.advance()V" + * + * @param args + */ + public static void main(String[] args) { + run(args); + } + + /** + * @param args + * -appJar [jar file name] -sig [method signature] The "jar file + * name" should be something like "c:/temp/testdata/java_cup.jar" The + * signature should be something like "java_cup.lexer.advance()V" + */ + public static Process run(String[] args) { + validateCommandLine(args); + return run(args[1], args[3]); + } + + /** + * @param appJar + * should be something like "c:/temp/testdata/java_cup.jar" + * @param methodSig + * should be something like "java_cup.lexer.advance()V" + */ + public static Process run(String appJar, String methodSig) { + try { + if (SWTCallGraph.isDirectory(appJar)) { + appJar = SWTCallGraph.findJarFiles(new String[] { appJar }); + } + EJavaAnalysisScope escope = JavaScopeUtil.makeAnalysisScope(appJar); + + // generate a DOMO-consumable wrapper around the incoming scope object + EMFScopeWrapper scope = EMFScopeWrapper.generateScope(escope); + + // invoke DOMO to build a DOMO class hierarchy object + WarningSet warnings = new WarningSet(); + ClassHierarchy cha = ClassHierarchy.make(scope, warnings); + + MethodReference mr = StringStuff.makeMethodReference(methodSig); + + IMethod m = cha.resolveMethod(mr); + if (m == null) { + Assertions.UNREACHABLE("could not resolve " + mr); + } + AnalysisOptions options = new AnalysisOptions(); + options.getSSAOptions().setUsePiNodes(true); + IR ir = options.getSSACache().findOrCreateIR(m, Everywhere.EVERYWHERE, cha, options.getSSAOptions(), new WarningSet()); + + if (ir == null) { + Assertions.UNREACHABLE("Null IR for " + m); + } + + System.err.println(ir.toString()); + + Properties wp = null; + try { + wp = WalaProperties.loadProperties(); + wp.putAll(WalaExamplesProperties.loadProperties()); + } catch (WalaException e) { + e.printStackTrace(); + Assertions.UNREACHABLE(); + } + String psFile = wp.getProperty(WalaProperties.OUTPUT_DIR) + File.separatorChar + GVWalaIR.PS_FILE; + String dotFile = wp.getProperty(WalaProperties.OUTPUT_DIR) + File.separatorChar + + GVTypeHierarchy.DOT_FILE; + String dotExe = wp.getProperty(WalaExamplesProperties.DOT_EXE); + String gvExe = wp.getProperty(WalaExamplesProperties.GHOSTVIEW_EXE); + + return GhostviewUtil.ghostviewIR(cha, ir, SANITIZE_CFG, psFile, dotFile, dotExe, gvExe); + + } catch (WalaException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + return null; + } + } + + /** + * Validate that the command-line arguments obey the expected usage. + * + * Usage: + *
                + *
              • args[0] : "-appJar" + *
              • args[1] : something like "c:/temp/testdata/java_cup.jar" + *
              • args[2] : "-sig" + *
              • args[3] : a method signature like "java_cup.lexer.advance()V" m = Environment.readEnv(); + + for (Iterator> it = m.entrySet().iterator(); it.hasNext();) { + System.out.println(it.next()); + } + } catch (WalaException e) { + e.printStackTrace(); + } + } +} diff --git a/com.ibm.wala.core.tests/com.ibm.wala.core.tests/src/com/ibm/wala/examples/drivers/SWTCallGraph.java b/com.ibm.wala.core.tests/com.ibm.wala.core.tests/src/com/ibm/wala/examples/drivers/SWTCallGraph.java new file mode 100644 index 000000000..45a1235a1 --- /dev/null +++ b/com.ibm.wala.core.tests/com.ibm.wala.core.tests/src/com/ibm/wala/examples/drivers/SWTCallGraph.java @@ -0,0 +1,198 @@ +/******************************************************************************* + * 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.examples.drivers; + +import java.io.File; +import java.util.Collection; +import java.util.Iterator; +import java.util.Properties; + +import org.eclipse.jface.window.ApplicationWindow; + +import com.ibm.wala.ecore.java.scope.EJavaAnalysisScope; +import com.ibm.wala.emf.wrappers.EMFScopeWrapper; +import com.ibm.wala.emf.wrappers.JavaScopeUtil; +import com.ibm.wala.examples.properties.WalaExamplesProperties; +import com.ibm.wala.ipa.callgraph.AnalysisOptions; +import com.ibm.wala.ipa.callgraph.CallGraph; +import com.ibm.wala.ipa.callgraph.CallGraphStats; +import com.ibm.wala.ipa.callgraph.Entrypoints; +import com.ibm.wala.ipa.callgraph.impl.Util; +import com.ibm.wala.ipa.cha.ClassHierarchy; +import com.ibm.wala.properties.WalaProperties; +import com.ibm.wala.util.collections.HashSetFactory; +import com.ibm.wala.util.debug.Assertions; +import com.ibm.wala.util.graph.GraphIntegrity; +import com.ibm.wala.util.graph.InferGraphRootsImpl; +import com.ibm.wala.util.io.CommandLine; +import com.ibm.wala.util.io.FileUtil; +import com.ibm.wala.util.perf.EngineTimings; +import com.ibm.wala.util.warnings.WalaException; +import com.ibm.wala.util.warnings.WarningSet; +import com.ibm.wala.viz.SWTTreeViewer; +import com.ibm.wala.viz.ViewIRAction; + +/** + * + * This application is a WALA client: it invokes an SWT TreeViewer to visualize + * a Call Graph + * + * @author sfink + */ +public class SWTCallGraph { + + private final static boolean CHECK_GRAPH = false; + + /** + * Usage: SWTCallGraph -appJar [jar file name] + * + * The "jar file name" should be something like + * "c:/temp/testdata/java_cup.jar" + * + * If it's a directory, then we'll try to find all jar files under that + * directory. + * + * @param args + * @throws WalaException + */ + public static void main(String[] args) throws WalaException { + Properties p = CommandLine.parse(args); + GVCallGraph.validateCommandLine(p); + run(p); + } + + /** + * @param p + * should contain at least the following properties: + *
                  + *
                • appJar should be something like + * "c:/temp/testdata/java_cup.jar" + *
                • algorithm (optional) can be one of: + *
                    + *
                  • "ZERO_CFA" (default value) + *
                  • "RTA" + *
                  + *
                + * + * @throws WalaException + */ + public static ApplicationWindow run(Properties p) throws WalaException { + + try { + String appJar = p.getProperty("appJar"); + if (isDirectory(appJar)) { + appJar = SWTCallGraph.findJarFiles(new String[] { appJar }); + } + EJavaAnalysisScope escope = JavaScopeUtil.makeAnalysisScope(appJar); + + String exclusionFile = p.getProperty("exclusions"); + if (exclusionFile != null) { + escope.setExclusionFileName(exclusionFile); + } + + // generate a DOMO-consumable wrapper around the incoming scope object + EMFScopeWrapper scope = EMFScopeWrapper.generateScope(escope); + + // TODO: return the warning set (need a CAPA type) + // invoke DOMO to build a DOMO class hierarchy object + WarningSet warnings = new WarningSet(); + ClassHierarchy cha = ClassHierarchy.make(scope, warnings); + + Entrypoints entrypoints = com.ibm.wala.ipa.callgraph.impl.Util.makeMainEntrypoints(scope, cha); + AnalysisOptions options = new AnalysisOptions(scope, entrypoints); + + // // + // build the call graph + // // + com.ibm.wala.ipa.callgraph.CallGraphBuilder builder = Util.makeZeroCFABuilder(options, cha, scope, warnings, null, null); + CallGraph cg = builder.makeCallGraph(options); + + System.out.println(CallGraphStats.getStats(cg)); + + if (CHECK_GRAPH) { + GraphIntegrity.check(cg); + } + + Properties wp = null; + try { + wp = WalaProperties.loadProperties(); + wp.putAll(WalaExamplesProperties.loadProperties()); + } catch (WalaException e) { + e.printStackTrace(); + Assertions.UNREACHABLE(); + } + String psFile = wp.getProperty(WalaProperties.OUTPUT_DIR) + File.separatorChar + GVWalaIR.PS_FILE; + String dotFile = wp.getProperty(WalaProperties.OUTPUT_DIR) + File.separatorChar + GVTypeHierarchy.DOT_FILE; + String dotExe = wp.getProperty(WalaExamplesProperties.DOT_EXE); + String gvExe = wp.getProperty(WalaExamplesProperties.GHOSTVIEW_EXE); + + // create and run the viewer + final SWTTreeViewer v = new SWTTreeViewer(); + v.setGraphInput(cg); + v.setRootsInput(InferGraphRootsImpl.inferRoots(cg)); + v.getPopUpActions().add(new ViewIRAction(v, cg, psFile, dotFile, dotExe, gvExe)); + v.run(); + return v.getApplicationWindow(); + + } catch (Exception e) { + e.printStackTrace(); + return null; + } finally { + EngineTimings.report(); + } + } + + // private static CallGraphConstructionAlgorithm chooseAlgorithm(Properties p) + // throws CapaException { + // String alg = p.getProperty("algorithm", "ZERO_CFA"); + // if (alg.equals("ZERO_CFA")) { + // return CallGraphConstructionAlgorithm.ZERO_CFA_LITERAL; + // } else if (alg.equals("RTA")) { + // return CallGraphConstructionAlgorithm.RTA_LITERAL; + // } else if (alg.equals("ZERO_ONE_CFA")) { + // return CallGraphConstructionAlgorithm.VANILLA_ZERO_ONE_CFA_LITERAL; + // } else { + // throw new CapaException("Unsupported algorithm: " + alg); + // } + // } + + static boolean isDirectory(String appJar) { + return (new File(appJar).isDirectory()); + } + + static String findJarFiles(String[] directories) throws WalaException { + Collection result = HashSetFactory.make(); + for (int i = 0; i < directories.length; i++) { + for (Iterator it = FileUtil.listFiles(directories[i], ".*\\.jar", true).iterator(); it.hasNext();) { + File f = (File) it.next(); + result.add(f.getAbsolutePath()); + } + } + return composeString(result); + } + + /** + * @param s + * Collection + */ + private static String composeString(Collection s) { + StringBuffer result = new StringBuffer(); + Iterator it = s.iterator(); + for (int i = 0; i < s.size() - 1; i++) { + result.append(it.next()); + result.append(';'); + } + if (it.hasNext()) { + result.append(it.next()); + } + return result.toString(); + } +} \ No newline at end of file diff --git a/com.ibm.wala.core.tests/com.ibm.wala.core.tests/src/com/ibm/wala/examples/drivers/SWTPointsTo.java b/com.ibm.wala.core.tests/com.ibm.wala.core.tests/src/com/ibm/wala/examples/drivers/SWTPointsTo.java new file mode 100644 index 000000000..ad78d888b --- /dev/null +++ b/com.ibm.wala.core.tests/com.ibm.wala.core.tests/src/com/ibm/wala/examples/drivers/SWTPointsTo.java @@ -0,0 +1,100 @@ +/******************************************************************************* + * 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.examples.drivers; + +import java.util.Properties; + +import org.eclipse.jface.window.ApplicationWindow; + +import com.ibm.wala.analysis.pointers.BasicHeapGraph; +import com.ibm.wala.ecore.java.scope.EJavaAnalysisScope; +import com.ibm.wala.emf.wrappers.EMFScopeWrapper; +import com.ibm.wala.emf.wrappers.JavaScopeUtil; +import com.ibm.wala.ipa.callgraph.AnalysisOptions; +import com.ibm.wala.ipa.callgraph.CallGraph; +import com.ibm.wala.ipa.callgraph.Entrypoints; +import com.ibm.wala.ipa.callgraph.impl.Util; +import com.ibm.wala.ipa.callgraph.propagation.PointerAnalysis; +import com.ibm.wala.ipa.cha.ClassHierarchy; +import com.ibm.wala.util.graph.Graph; +import com.ibm.wala.util.graph.InferGraphRootsImpl; +import com.ibm.wala.util.io.CommandLine; +import com.ibm.wala.util.warnings.WalaException; +import com.ibm.wala.util.warnings.WarningSet; +import com.ibm.wala.viz.SWTTreeViewer; + +/** + * + * This application is a WALA client: it invokes an SWT TreeViewer to visualize + * a Points-To solution + * + * @author sfink + */ +public class SWTPointsTo { + + /** + * Usage: SWTPointsTo -appJar [jar file name] The "jar file name" should be + * something like "c:/temp/testdata/java_cup.jar" + * + * @param args + */ + public static void main(String[] args) { + Properties p = CommandLine.parse(args); + GVCallGraph.validateCommandLine(p); + run(p.getProperty("appJar")); + } + + /** + * @param appJar + * should be something like "c:/temp/testdata/java_cup.jar" + */ + public static ApplicationWindow run(String appJar) { + + try { + Graph g = buildPointsTo(appJar); + + // create and run the viewer + final SWTTreeViewer v = new SWTTreeViewer(); + v.setGraphInput(g); + v.setRootsInput(InferGraphRootsImpl.inferRoots(g)); + v.run(); + return v.getApplicationWindow(); + + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } + + public static Graph buildPointsTo(String appJar) throws WalaException { + EJavaAnalysisScope escope = JavaScopeUtil.makeAnalysisScope(appJar); + + // generate a DOMO-consumable wrapper around the incoming scope object + EMFScopeWrapper scope = EMFScopeWrapper.generateScope(escope); + + + // TODO: return the warning set (need a CAPA type) + // invoke DOMO to build a DOMO class hierarchy object + WarningSet warnings = new WarningSet(); + ClassHierarchy cha = ClassHierarchy.make(scope, warnings); + + Entrypoints entrypoints = com.ibm.wala.ipa.callgraph.impl.Util.makeMainEntrypoints(scope, cha); + AnalysisOptions options = new AnalysisOptions(scope, entrypoints); + + // // + // build the call graph + // // + com.ibm.wala.ipa.callgraph.CallGraphBuilder builder = Util.makeZeroCFABuilder(options, cha, scope, warnings, null, null); + CallGraph cg = builder.makeCallGraph(options); + PointerAnalysis pointerAnalysis = builder.getPointerAnalysis(); + return new BasicHeapGraph(pointerAnalysis,cg); + } +} \ No newline at end of file diff --git a/com.ibm.wala.core.tests/com.ibm.wala.core.tests/src/com/ibm/wala/examples/drivers/SWTTypeHierarchy.java b/com.ibm.wala.core.tests/com.ibm.wala.core.tests/src/com/ibm/wala/examples/drivers/SWTTypeHierarchy.java new file mode 100644 index 000000000..51b80d45c --- /dev/null +++ b/com.ibm.wala.core.tests/com.ibm.wala.core.tests/src/com/ibm/wala/examples/drivers/SWTTypeHierarchy.java @@ -0,0 +1,75 @@ +/******************************************************************************* + * 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.examples.drivers; + +import java.util.Collection; + +import org.eclipse.emf.ecore.EObject; +import org.eclipse.jface.window.ApplicationWindow; + +import com.ibm.wala.ecore.java.ETypeHierarchy; +import com.ibm.wala.util.graph.Graph; +import com.ibm.wala.util.graph.InferGraphRootsImpl; +import com.ibm.wala.viz.SWTTreeViewer; + +/** + * + * This application is a WALA client: it invokes an SWT TreeViewer to visualize + * a TypeHierarchy in a precomputed file serialized on disk. So, you must run + * ExportTypeHierarchyToXML before running this, to compute the type hierarchy and + * serialize it to disk. + * + * @author sfink + */ +public class SWTTypeHierarchy { + + /** + * Usage: SWTTreeViewerBasicPipeline + */ + public static void main(String[] args) { + run(); + } + + public static ApplicationWindow run() { + + try { + ETypeHierarchy th = GVTypeHierarchy.readTypeHierarchy(); + if (th.getClasses().getNodes().getContents().size() <1) { + System.err.println("PANIC: th # classes=" + th.getClasses().getNodes().getContents().size()); + System.exit(-1); + } + + Graph g = GVTypeHierarchy.typeHierarchy2Graph(th); + g = GVTypeHierarchy.pruneForAppLoader(g); + + if (g.getNumberOfNodes() == 0) { + System.err.println("ERROR: The type hierarchy in " + ExportTypeHierarchyToXML.getFileName() + " has no nodes from the Application loader"); + System.exit(-1); + } + + // create and run the viewer + final SWTTreeViewer v =new SWTTreeViewer(); + v.setGraphInput(g); + Collection roots = InferGraphRootsImpl.inferRoots(g); + if (roots.size() < 1) { + System.err.println("PANIC: roots.size()=" + roots.size()); + System.exit(-1); + } + v.setRootsInput(roots); + v.run(); + return v.getApplicationWindow(); + + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } +} \ No newline at end of file diff --git a/com.ibm.wala.core.tests/com.ibm.wala.core.tests/src/com/ibm/wala/examples/properties/WalaExamplesProperties.java b/com.ibm.wala.core.tests/com.ibm.wala.core.tests/src/com/ibm/wala/examples/properties/WalaExamplesProperties.java new file mode 100644 index 000000000..d84770800 --- /dev/null +++ b/com.ibm.wala.core.tests/com.ibm.wala.core.tests/src/com/ibm/wala/examples/properties/WalaExamplesProperties.java @@ -0,0 +1,50 @@ +/******************************************************************************* + * 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.examples.properties; + +import java.io.File; +import java.net.URL; +import java.util.Properties; + +import com.ibm.wala.properties.WalaProperties; +import com.ibm.wala.util.config.FileProvider; +import com.ibm.wala.util.warnings.WalaException; + +public final class WalaExamplesProperties { + + public static final String GHOSTVIEW_EXE = "ghostview_exe"; //$NON-NLS-1$ + + public static final String DOT_EXE = "dot_exe"; //$NON-NLS-1$ + + public final static String PROPERTY_FILENAME = "wala.examples.properties"; //$NON-NLS-1$ + + public static Properties loadProperties() throws WalaException { + + try { + Properties result = WalaProperties.loadPropertiesFromFile(PROPERTY_FILENAME); + + return result; + } catch (Exception e) { + e.printStackTrace(); + throw new WalaException("Unable to set up wala examples properties ", e); + } + } + + public static String getWalaCoreTestsHomeDirectory() throws WalaException { + final URL url = WalaExamplesProperties.class.getClassLoader().getResource(PROPERTY_FILENAME); + if (url == null) { + throw new WalaException("failed to find URL for capa.examples.properties"); + } + + return new File(FileProvider.filePathFromURL(url)).getParentFile().getParentFile().getAbsolutePath(); + } + +} \ No newline at end of file diff --git a/com.ibm.wala.core.tests/dat/GUIExclusions.xml b/com.ibm.wala.core.tests/dat/GUIExclusions.xml new file mode 100644 index 000000000..26c02a0a9 --- /dev/null +++ b/com.ibm.wala.core.tests/dat/GUIExclusions.xml @@ -0,0 +1,4 @@ + + + + diff --git a/com.ibm.wala.core.tests/dat/JLex.xml b/com.ibm.wala.core.tests/dat/JLex.xml new file mode 100644 index 000000000..7e578b02b --- /dev/null +++ b/com.ibm.wala.core.tests/dat/JLex.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/com.ibm.wala.core.tests/dat/bcel.xml b/com.ibm.wala.core.tests/dat/bcel.xml new file mode 100644 index 000000000..9201ec117 --- /dev/null +++ b/com.ibm.wala.core.tests/dat/bcel.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/com.ibm.wala.core.tests/dat/hello.xml b/com.ibm.wala.core.tests/dat/hello.xml new file mode 100644 index 000000000..5d6e0eccb --- /dev/null +++ b/com.ibm.wala.core.tests/dat/hello.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/com.ibm.wala.core.tests/dat/java_cup.xml b/com.ibm.wala.core.tests/dat/java_cup.xml new file mode 100644 index 000000000..0935a098f --- /dev/null +++ b/com.ibm.wala.core.tests/dat/java_cup.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/com.ibm.wala.core.tests/dat/wala.examples.properties.sample b/com.ibm.wala.core.tests/dat/wala.examples.properties.sample new file mode 100644 index 000000000..c48518f92 --- /dev/null +++ b/com.ibm.wala.core.tests/dat/wala.examples.properties.sample @@ -0,0 +1,30 @@ +############################################################################### +# WALA Examples property file +# This file defines the default settings for the WALA examples +############################################################################### + +################# Mandatory settings without default value #################### + +################### Mandatory settings with default value ###################### + + +############################ Optional settings ################################ + +### These are needed to run various individual examples + + +##### Ghostview executable +# Path to the ghostview executable +# For instance, on a windows OS it's typically something like C:/Progra~1/Ghostgum/gsview/gsview32.exe +# Default value: none +# Info: Must be absolute path +##### +#ghostview_exe = Your location + +##### DOT executable +# Path to the AT&T Graphview DOT executable +# For instance, on a windows OS it's typically something like C:/Progra~1/ATT/Graphviz/bin/dot.exe +# Default value: none +# Info: Must be absolute path +##### +#dot_exe = Your location diff --git a/com.ibm.wala.core.tests/dat/wala.testdata.xml b/com.ibm.wala.core.tests/dat/wala.testdata.xml new file mode 100644 index 000000000..e579cb64e --- /dev/null +++ b/com.ibm.wala.core.tests/dat/wala.testdata.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/com.ibm.wala.core.tests/javaCompiler...args b/com.ibm.wala.core.tests/javaCompiler...args new file mode 100644 index 000000000..c1f7e058e --- /dev/null +++ b/com.ibm.wala.core.tests/javaCompiler...args @@ -0,0 +1,42 @@ +#ADAPTER#ACCESS#com.ibm.wala.core/bin/[+com/ibm/wala/analysis/pointers/*;+com/ibm/wala/analysis/reflection/*;+com/ibm/wala/analysis/stackMachine/*;+com/ibm/wala/analysis/typeInference/*;+com/ibm/wala/cfg/*;+com/ibm/wala/cfg/cdg/*;+com/ibm/wala/classLoader/*;+com/ibm/wala/client/*;+com/ibm/wala/client/impl/*;+com/ibm/wala/core/plugin/*;+com/ibm/wala/dataflow/IFDS/*;+com/ibm/wala/dataflow/graph/*;+com/ibm/wala/dataflow/ssa/*;+com/ibm/wala/emf/wrappers/*;+com/ibm/wala/escape/*;+com/ibm/wala/fixedpoint/impl/*;+com/ibm/wala/fixpoint/*;+com/ibm/wala/ipa/callgraph/*;+com/ibm/wala/ipa/callgraph/impl/*;+com/ibm/wala/ipa/callgraph/propagation/*;+com/ibm/wala/ipa/callgraph/propagation/cfa/*;+com/ibm/wala/ipa/callgraph/propagation/rta/*;+com/ibm/wala/ipa/cfg/*;+com/ibm/wala/ipa/cha/*;+com/ibm/wala/ipa/summaries/*;+com/ibm/wala/model/*;+com/ibm/wala/model/java/lang/*;+com/ibm/wala/properties/*;+com/ibm/wala/ssa/*;+com/ibm/wala/ssa/analysis/*;+com/ibm/wala/types/*;+com/ibm/wala/util/*;+com/ibm/wala/util/bytecode/*;+com/ibm/wala/util/collections/*;+com/ibm/wala/util/config/*;+com/ibm/wala/util/debug/*;+com/ibm/wala/util/graph/*;+com/ibm/wala/util/graph/impl/*;+com/ibm/wala/util/graph/traverse/*;+com/ibm/wala/util/heapTrace/*;+com/ibm/wala/util/intertionalization/*;+com/ibm/wala/util/intset/*;+com/ibm/wala/util/io/*;+com/ibm/wala/util/logging/*;+com/ibm/wala/util/math/*;+com/ibm/wala/util/perf/*;+com/ibm/wala/util/properties/*;+com/ibm/wala/util/properties/impl/*;+com/ibm/wala/util/warnings/*;+com/ibm/wala/viz/*;?**/*] +#ADAPTER#ACCESS#com.ibm.wala.core/@dot[+com/ibm/wala/analysis/pointers/*;+com/ibm/wala/analysis/reflection/*;+com/ibm/wala/analysis/stackMachine/*;+com/ibm/wala/analysis/typeInference/*;+com/ibm/wala/cfg/*;+com/ibm/wala/cfg/cdg/*;+com/ibm/wala/classLoader/*;+com/ibm/wala/client/*;+com/ibm/wala/client/impl/*;+com/ibm/wala/core/plugin/*;+com/ibm/wala/dataflow/IFDS/*;+com/ibm/wala/dataflow/graph/*;+com/ibm/wala/dataflow/ssa/*;+com/ibm/wala/emf/wrappers/*;+com/ibm/wala/escape/*;+com/ibm/wala/fixedpoint/impl/*;+com/ibm/wala/fixpoint/*;+com/ibm/wala/ipa/callgraph/*;+com/ibm/wala/ipa/callgraph/impl/*;+com/ibm/wala/ipa/callgraph/propagation/*;+com/ibm/wala/ipa/callgraph/propagation/cfa/*;+com/ibm/wala/ipa/callgraph/propagation/rta/*;+com/ibm/wala/ipa/cfg/*;+com/ibm/wala/ipa/cha/*;+com/ibm/wala/ipa/summaries/*;+com/ibm/wala/model/*;+com/ibm/wala/model/java/lang/*;+com/ibm/wala/properties/*;+com/ibm/wala/ssa/*;+com/ibm/wala/ssa/analysis/*;+com/ibm/wala/types/*;+com/ibm/wala/util/*;+com/ibm/wala/util/bytecode/*;+com/ibm/wala/util/collections/*;+com/ibm/wala/util/config/*;+com/ibm/wala/util/debug/*;+com/ibm/wala/util/graph/*;+com/ibm/wala/util/graph/impl/*;+com/ibm/wala/util/graph/traverse/*;+com/ibm/wala/util/heapTrace/*;+com/ibm/wala/util/intertionalization/*;+com/ibm/wala/util/intset/*;+com/ibm/wala/util/io/*;+com/ibm/wala/util/logging/*;+com/ibm/wala/util/math/*;+com/ibm/wala/util/perf/*;+com/ibm/wala/util/properties/*;+com/ibm/wala/util/properties/impl/*;+com/ibm/wala/util/warnings/*;+com/ibm/wala/viz/*;?**/*] +#ADAPTER#ACCESS#com.ibm.wala.emf/bin/[+com/ibm/wala/ecore/common/*;+com/ibm/wala/ecore/common/impl/*;+com/ibm/wala/ecore/common/util/*;+com/ibm/wala/ecore/graph/*;+com/ibm/wala/ecore/graph/impl/*;+com/ibm/wala/ecore/graph/util/*;+com/ibm/wala/ecore/j2ee/scope/*;+com/ibm/wala/ecore/j2ee/scope/impl/*;+com/ibm/wala/ecore/j2ee/scope/util/*;+com/ibm/wala/ecore/java/*;+com/ibm/wala/ecore/java/callGraph/*;+com/ibm/wala/ecore/java/callGraph/impl/*;+com/ibm/wala/ecore/java/callGraph/util/*;+com/ibm/wala/ecore/java/impl/*;+com/ibm/wala/ecore/java/pointerAnalysis/*;+com/ibm/wala/ecore/java/pointerAnalysis/impl/*;+com/ibm/wala/ecore/java/pointerAnalysis/util/*;+com/ibm/wala/ecore/java/scope/*;+com/ibm/wala/ecore/java/scope/impl/*;+com/ibm/wala/ecore/java/scope/util/*;+com/ibm/wala/ecore/java/util/*;+com/ibm/wala/ecore/perf/*;+com/ibm/wala/ecore/perf/impl/*;+com/ibm/wala/ecore/perf/util/*;+com/ibm/wala/ecore/regex/*;+com/ibm/wala/ecore/regex/impl/*;+com/ibm/wala/ecore/regex/util/*;?**/*] +#ADAPTER#ACCESS#com.ibm.wala.emf/@dot[+com/ibm/wala/ecore/common/*;+com/ibm/wala/ecore/common/impl/*;+com/ibm/wala/ecore/common/util/*;+com/ibm/wala/ecore/graph/*;+com/ibm/wala/ecore/graph/impl/*;+com/ibm/wala/ecore/graph/util/*;+com/ibm/wala/ecore/j2ee/scope/*;+com/ibm/wala/ecore/j2ee/scope/impl/*;+com/ibm/wala/ecore/j2ee/scope/util/*;+com/ibm/wala/ecore/java/*;+com/ibm/wala/ecore/java/callGraph/*;+com/ibm/wala/ecore/java/callGraph/impl/*;+com/ibm/wala/ecore/java/callGraph/util/*;+com/ibm/wala/ecore/java/impl/*;+com/ibm/wala/ecore/java/pointerAnalysis/*;+com/ibm/wala/ecore/java/pointerAnalysis/impl/*;+com/ibm/wala/ecore/java/pointerAnalysis/util/*;+com/ibm/wala/ecore/java/scope/*;+com/ibm/wala/ecore/java/scope/impl/*;+com/ibm/wala/ecore/java/scope/util/*;+com/ibm/wala/ecore/java/util/*;+com/ibm/wala/ecore/perf/*;+com/ibm/wala/ecore/perf/impl/*;+com/ibm/wala/ecore/perf/util/*;+com/ibm/wala/ecore/regex/*;+com/ibm/wala/ecore/regex/impl/*;+com/ibm/wala/ecore/regex/util/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.core.runtime_3.2.0.v20060603.jar[~org/eclipse/core/internal/preferences/legacy/*;~org/eclipse/core/internal/runtime/*;+org/eclipse/core/runtime/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.osgi_3.2.0.v20060601.jar[+org/eclipse/osgi/event/*;+org/eclipse/osgi/framework/console/*;+org/eclipse/osgi/framework/eventmgr/*;+org/eclipse/osgi/framework/log/*;+org/eclipse/osgi/service/datalocation/*;+org/eclipse/osgi/service/debug/*;+org/eclipse/osgi/service/environment/*;+org/eclipse/osgi/service/localization/*;+org/eclipse/osgi/service/pluginconversion/*;+org/eclipse/osgi/service/resolver/*;+org/eclipse/osgi/service/runnable/*;+org/eclipse/osgi/service/urlconversion/*;+org/eclipse/osgi/storagemanager/*;+org/eclipse/osgi/util/*;+org/osgi/framework/*;+org/osgi/service/condpermadmin/*;+org/osgi/service/packageadmin/*;+org/osgi/service/permissionadmin/*;+org/osgi/service/startlevel/*;+org/osgi/service/url/*;+org/osgi/util/tracker/*;~org/eclipse/core/runtime/adaptor/*;~org/eclipse/core/runtime/internal/adaptor/*;~org/eclipse/core/runtime/internal/stats/*;~org/eclipse/osgi/baseadaptor/*;~org/eclipse/osgi/baseadaptor/bundlefile/*;~org/eclipse/osgi/baseadaptor/hooks/*;~org/eclipse/osgi/baseadaptor/loader/*;~org/eclipse/osgi/framework/adaptor/*;~org/eclipse/osgi/framework/debug/*;~org/eclipse/osgi/framework/internal/core/*;~org/eclipse/osgi/framework/internal/protocol/*;~org/eclipse/osgi/framework/internal/protocol/bundleentry/*;~org/eclipse/osgi/framework/internal/protocol/bundleresource/*;~org/eclipse/osgi/framework/internal/protocol/reference/*;~org/eclipse/osgi/framework/internal/reliablefile/*;~org/eclipse/osgi/framework/launcher/*;~org/eclipse/osgi/framework/util/*;~org/eclipse/osgi/internal/baseadaptor/*;~org/eclipse/osgi/internal/module/*;~org/eclipse/osgi/internal/profile/*;~org/eclipse/osgi/internal/resolver/*;~org/eclipse/osgi/internal/verifier/*;~org/eclipse/osgi/internal/provisional/verifier/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.equinox.common_3.2.0.v20060603.jar[~org/eclipse/core/internal/runtime/*;~org/eclipse/core/internal/boot/*;+org/eclipse/core/runtime/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.core.jobs_3.2.0.v20060603.jar[~org/eclipse/core/internal/jobs/*;+org/eclipse/core/runtime/jobs/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.core.runtime.compatibility.registry_3.2.0.v20060603/runtime_registry_compatibility.jar[~org/eclipse/core/internal/registry/*;~org/eclipse/core/internal/registry/osgi/*;~org/eclipse/core/internal/registry/spi/*;+org/eclipse/core/runtime/*;+org/eclipse/core/runtime/dynamichelpers/*;+org/eclipse/core/runtime/spi/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.core.runtime.compatibility.registry_3.2.0.v20060603[~org/eclipse/core/internal/registry/*;~org/eclipse/core/internal/registry/osgi/*;~org/eclipse/core/internal/registry/spi/*;+org/eclipse/core/runtime/*;+org/eclipse/core/runtime/dynamichelpers/*;+org/eclipse/core/runtime/spi/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.equinox.registry_3.2.0.v20060601.jar[~org/eclipse/core/internal/registry/*;~org/eclipse/core/internal/registry/osgi/*;~org/eclipse/core/internal/registry/spi/*;+org/eclipse/core/runtime/*;+org/eclipse/core/runtime/dynamichelpers/*;+org/eclipse/core/runtime/spi/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.apache.xerces_2.8.0.v200606131651/resolver.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.apache.xerces_2.8.0.v200606131651/xercesImpl.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.apache.xerces_2.8.0.v200606131651/xml-apis.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.equinox.preferences_3.2.0.v20060601.jar[~org/eclipse/core/internal/preferences/*;~org/eclipse/core/internal/preferences/exchange/*;+org/eclipse/core/runtime/preferences/*;+org/osgi/service/prefs/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.core.runtime.compatibility.registry_3.2.0.v20060603/@dot[~org/eclipse/core/internal/registry/*;~org/eclipse/core/internal/registry/osgi/*;~org/eclipse/core/internal/registry/spi/*;+org/eclipse/core/runtime/*;+org/eclipse/core/runtime/dynamichelpers/*;+org/eclipse/core/runtime/spi/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.core.contenttype_3.2.0.v20060603.jar[~org/eclipse/core/internal/content/*;+org/eclipse/core/runtime/content/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.core.runtime.compatibility.auth_3.2.0.v20060601.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.emf.ecore_2.2.0.v200606271057.jar[+org/eclipse/emf/ecore/*;+org/eclipse/emf/ecore/impl/*;+org/eclipse/emf/ecore/plugin/*;+org/eclipse/emf/ecore/resource/*;+org/eclipse/emf/ecore/resource/impl/*;+org/eclipse/emf/ecore/util/*;+org/eclipse/emf/ecore/xml/namespace/*;+org/eclipse/emf/ecore/xml/namespace/impl/*;+org/eclipse/emf/ecore/xml/namespace/util/*;+org/eclipse/emf/ecore/xml/type/*;+org/eclipse/emf/ecore/xml/type/impl/*;+org/eclipse/emf/ecore/xml/type/internal/*;+org/eclipse/emf/ecore/xml/type/util/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.emf.common_2.2.0.v200606271057.jar[+org/eclipse/emf/common/*;+org/eclipse/emf/common/archive/*;+org/eclipse/emf/common/command/*;+org/eclipse/emf/common/notify/*;+org/eclipse/emf/common/notify/impl/*;+org/eclipse/emf/common/util/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.core.resources_3.2.0.v20060603.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.core.resources.compatibility_3.2.0.v20060603.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.core.resources.win32_3.2.0.v20060603.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.core.runtime.compatibility_3.1.100.v20060603.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.update.configurator_3.2.0.v20060605.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.ant.core_3.1.100.v20060531.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.core.variables_3.1.100.v20060605.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.core.expressions_3.2.0.v20060605-1400.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.core.filesystem_1.0.0.v20060603.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.core.filesystem.win32.x86_1.0.0.v20060603.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.emf.ecore.xmi_2.2.0.v200606271057.jar[+org/eclipse/emf/ecore/xmi/*;+org/eclipse/emf/ecore/xmi/impl/*;+org/eclipse/emf/ecore/xmi/util/*;?**/*] +#ADAPTER#ACCESS#com.ibm.wala.shrike/bin/[+com/ibm/wala/shrike/bench/*;+com/ibm/wala/shrike/copywriter/*;+com/ibm/wala/shrike/tools/*;+com/ibm/wala/shrikeBT/*;+com/ibm/wala/shrikeBT/analysis/*;+com/ibm/wala/shrikeBT/info/*;+com/ibm/wala/shrikeBT/shrikeCT/*;+com/ibm/wala/shrikeBT/shrikeCT/tools/*;+com/ibm/wala/shrikeBT/tools/*;+com/ibm/wala/shrikeCT/*;?**/*] +#ADAPTER#ACCESS#com.ibm.wala.shrike/@dot[+com/ibm/wala/shrike/bench/*;+com/ibm/wala/shrike/copywriter/*;+com/ibm/wala/shrike/tools/*;+com/ibm/wala/shrikeBT/*;+com/ibm/wala/shrikeBT/analysis/*;+com/ibm/wala/shrikeBT/info/*;+com/ibm/wala/shrikeBT/shrikeCT/*;+com/ibm/wala/shrikeBT/shrikeCT/tools/*;+com/ibm/wala/shrikeBT/tools/*;+com/ibm/wala/shrikeCT/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.jface_3.2.0.I20060605-1400.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.swt_3.2.0.v3232o.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.swt.win32.win32.x86_3.2.0.v3232m.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.core.commands_3.2.0.I20060605-1400.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.jdt.core_3.2.0.v_671.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.text_3.2.0.v20060605-1400.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/com.ibm.icu_3.4.4.1.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.team.core_3.2.0.I200606051140.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.junit_3.8.1/junit.jar[+junit/awtui/*;+junit/extensions/*;+junit/framework/*;+junit/runner/*;+junit/swingui/*;+junit/swingui/icons/*;+junit/textui/*;?**/*] diff --git a/com.ibm.wala.core.tests/launchers/ExportCallGraphToXML.launch b/com.ibm.wala.core.tests/launchers/ExportCallGraphToXML.launch new file mode 100644 index 000000000..5abbcec37 --- /dev/null +++ b/com.ibm.wala.core.tests/launchers/ExportCallGraphToXML.launch @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/com.ibm.wala.core.tests/launchers/ExportTypeHierarchyToXML.launch b/com.ibm.wala.core.tests/launchers/ExportTypeHierarchyToXML.launch new file mode 100644 index 000000000..e272ce68a --- /dev/null +++ b/com.ibm.wala.core.tests/launchers/ExportTypeHierarchyToXML.launch @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/com.ibm.wala.core.tests/launchers/GVCallGraph.launch b/com.ibm.wala.core.tests/launchers/GVCallGraph.launch new file mode 100644 index 000000000..0f56985de --- /dev/null +++ b/com.ibm.wala.core.tests/launchers/GVCallGraph.launch @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/com.ibm.wala.core.tests/launchers/GVControlDependenceGraph.launch b/com.ibm.wala.core.tests/launchers/GVControlDependenceGraph.launch new file mode 100644 index 000000000..de8197e8d --- /dev/null +++ b/com.ibm.wala.core.tests/launchers/GVControlDependenceGraph.launch @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/com.ibm.wala.core.tests/launchers/GVSDG.launch b/com.ibm.wala.core.tests/launchers/GVSDG.launch new file mode 100644 index 000000000..c361a3962 --- /dev/null +++ b/com.ibm.wala.core.tests/launchers/GVSDG.launch @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/com.ibm.wala.core.tests/launchers/GVSlice.launch b/com.ibm.wala.core.tests/launchers/GVSlice.launch new file mode 100644 index 000000000..d059c9c67 --- /dev/null +++ b/com.ibm.wala.core.tests/launchers/GVSlice.launch @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/com.ibm.wala.core.tests/launchers/GVTypeHierarchy.launch b/com.ibm.wala.core.tests/launchers/GVTypeHierarchy.launch new file mode 100644 index 000000000..860864583 --- /dev/null +++ b/com.ibm.wala.core.tests/launchers/GVTypeHierarchy.launch @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/com.ibm.wala.core.tests/launchers/GVWalaIR.launch b/com.ibm.wala.core.tests/launchers/GVWalaIR.launch new file mode 100644 index 000000000..1b04da957 --- /dev/null +++ b/com.ibm.wala.core.tests/launchers/GVWalaIR.launch @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/com.ibm.wala.core.tests/launchers/GetEnv.launch b/com.ibm.wala.core.tests/launchers/GetEnv.launch new file mode 100644 index 000000000..ea2696a61 --- /dev/null +++ b/com.ibm.wala.core.tests/launchers/GetEnv.launch @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/com.ibm.wala.core.tests/launchers/SWTCallGraph.launch b/com.ibm.wala.core.tests/launchers/SWTCallGraph.launch new file mode 100644 index 000000000..daac4b660 --- /dev/null +++ b/com.ibm.wala.core.tests/launchers/SWTCallGraph.launch @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/com.ibm.wala.core.tests/launchers/SWTPointsTo.launch b/com.ibm.wala.core.tests/launchers/SWTPointsTo.launch new file mode 100644 index 000000000..5b6675f32 --- /dev/null +++ b/com.ibm.wala.core.tests/launchers/SWTPointsTo.launch @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/com.ibm.wala.core.tests/launchers/SWTTypeHierarchy.launch b/com.ibm.wala.core.tests/launchers/SWTTypeHierarchy.launch new file mode 100644 index 000000000..f2a2fd62b --- /dev/null +++ b/com.ibm.wala.core.tests/launchers/SWTTypeHierarchy.launch @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/com.ibm.wala.core.tests/launchers/SimpleThreadEscapeAnalysis.launch b/com.ibm.wala.core.tests/launchers/SimpleThreadEscapeAnalysis.launch new file mode 100644 index 000000000..08d5bb91c --- /dev/null +++ b/com.ibm.wala.core.tests/launchers/SimpleThreadEscapeAnalysis.launch @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/com.ibm.wala.core.tests/launchers/SlicerTest.launch b/com.ibm.wala.core.tests/launchers/SlicerTest.launch new file mode 100644 index 000000000..fb0df2962 --- /dev/null +++ b/com.ibm.wala.core.tests/launchers/SlicerTest.launch @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/com.ibm.wala.core.tests/launchers/wala.core short profile.launch b/com.ibm.wala.core.tests/launchers/wala.core short profile.launch new file mode 100644 index 000000000..c1a77a6f1 --- /dev/null +++ b/com.ibm.wala.core.tests/launchers/wala.core short profile.launch @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/com.ibm.wala.core.tests/launchers/wala.core.launch b/com.ibm.wala.core.tests/launchers/wala.core.launch new file mode 100644 index 000000000..4214916d0 --- /dev/null +++ b/com.ibm.wala.core.tests/launchers/wala.core.launch @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/com.ibm.wala.core.tests/src/com/ibm/wala/core/tests/basic/GraphDataflowTest.java b/com.ibm.wala.core.tests/src/com/ibm/wala/core/tests/basic/GraphDataflowTest.java new file mode 100644 index 000000000..e37aecd75 --- /dev/null +++ b/com.ibm.wala.core.tests/src/com/ibm/wala/core/tests/basic/GraphDataflowTest.java @@ -0,0 +1,214 @@ +/******************************************************************************* + * 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.core.tests.basic; + +import com.ibm.wala.core.tests.util.WalaTestCase; +import com.ibm.wala.dataflow.graph.AbstractMeetOperator; +import com.ibm.wala.dataflow.graph.BitVectorFilter; +import com.ibm.wala.dataflow.graph.BitVectorFramework; +import com.ibm.wala.dataflow.graph.BitVectorIdentity; +import com.ibm.wala.dataflow.graph.BitVectorSolver; +import com.ibm.wala.dataflow.graph.BitVectorUnion; +import com.ibm.wala.dataflow.graph.BitVectorUnionConstant; +import com.ibm.wala.dataflow.graph.DataflowSolver; +import com.ibm.wala.dataflow.graph.ITransferFunctionProvider; +import com.ibm.wala.fixedpoint.impl.UnaryOperator; +import com.ibm.wala.fixpoint.BitVectorVariable; +import com.ibm.wala.util.debug.Assertions; +import com.ibm.wala.util.graph.Graph; +import com.ibm.wala.util.graph.impl.SlowSparseNumberedGraph; +import com.ibm.wala.util.intset.BitVector; +import com.ibm.wala.util.intset.MutableMapping; +import com.ibm.wala.util.intset.OrdinalSetMapping; + +/** + * + * Simple Regression test for a graph-based dataflow problem + * + * @author Donald P Pazel + * @author sfink + * @author Julian Dolby (dolby@us.ibm.com) + */ +public class GraphDataflowTest extends WalaTestCase { + + public static final String nodeNames = "ABCDEFGH"; + protected final static String[] nodes = new String[nodeNames.length()]; + + public GraphDataflowTest() { + super("GraphDataflowTest"); + } + + /** + * A simple test of the GraphBitVectorDataflow system + */ + public void testSolverNodeEdge() { + Graph G = buildGraph(); + String result = solveNodeEdge(G); + System.err.println(result); + if (!result.equals(expectedStringNodeEdge())) { + System.err.println("Uh oh."); + System.err.println(expectedStringNodeEdge()); + } + assertEquals(expectedStringNodeEdge(), result); + } + + public void testSolverNodeOnly() { + Graph G = buildGraph(); + String result = solveNodeOnly(G); + System.err.println(result); + assertEquals(expectedStringNodeOnly(), result); + } + + /** + * @return the expected dataflow result as a String + */ + public static String expectedStringNodeOnly() { + StringBuffer result = new StringBuffer("------\n"); + result.append("Node A(0) = { 0 }\n"); + result.append("Node B(1) = { 0 1 }\n"); + result.append("Node C(2) = { 0 1 2 }\n"); + result.append("Node D(3) = { 0 1 3 }\n"); + result.append("Node E(4) = { 0 1 2 3 4 }\n"); + result.append("Node F(5) = { 0 1 2 3 4 5 }\n"); + result.append("Node G(6) = { 6 }\n"); + result.append("Node H(7) = { 7 }\n"); + return result.toString(); + } + + public static String expectedStringNodeEdge() { + StringBuffer result = new StringBuffer("------\n"); + result.append("Node A(0) = { 0 }\n"); + result.append("Node B(1) = { 0 1 }\n"); + result.append("Node C(2) = { 0 2 }\n"); + result.append("Node D(3) = { 1 3 }\n"); + result.append("Node E(4) = { 0 1 2 3 4 }\n"); + result.append("Node F(5) = { 0 1 2 3 4 5 }\n"); + result.append("Node G(6) = { 6 }\n"); + result.append("Node H(7) = { 7 }\n"); + return result.toString(); + } + + /** + * @return a graph with the expected structure + */ + private static Graph buildGraph() { + Graph G = new SlowSparseNumberedGraph(); + for (int i = 0; i < nodeNames.length(); i++) { + String n = nodeNames.substring(i, i + 1); + G.addNode(n); + nodes[i] = n; + } + G.addEdge(nodes[0], nodes[1]); + G.addEdge(nodes[1], nodes[2]); + G.addEdge(nodes[1], nodes[3]); + G.addEdge(nodes[2], nodes[4]); + G.addEdge(nodes[3], nodes[4]); + G.addEdge(nodes[4], nodes[5]); + return G; + } + + /** + * Solve the dataflow system and return the result as a string + */ + private String solveNodeOnly(Graph G) { + final OrdinalSetMapping values = new MutableMapping(nodes); + ITransferFunctionProvider functions = new ITransferFunctionProvider() { + + public UnaryOperator getNodeTransferFunction(String node) { + return new BitVectorUnionConstant(values.getMappedIndex(node)); + } + + public boolean hasNodeTransferFunctions() { + return true; + } + + public UnaryOperator getEdgeTransferFunction(String from, String to) { + Assertions.UNREACHABLE(); + return null; + } + + public boolean hasEdgeTransferFunctions() { + return false; + } + + public AbstractMeetOperator getMeetOperator() { + return BitVectorUnion.instance(); + } + + }; + + BitVectorFramework F = new BitVectorFramework(G, functions, values); + DataflowSolver s = new BitVectorSolver(F); + s.solve(); + return result2String(s); + } + + private String solveNodeEdge(Graph G) { + final OrdinalSetMapping values = new MutableMapping(nodes); + ITransferFunctionProvider functions = new ITransferFunctionProvider() { + + public UnaryOperator getNodeTransferFunction(String node) { + return new BitVectorUnionConstant(values.getMappedIndex(node)); + } + + public boolean hasNodeTransferFunctions() { + return true; + } + + private BitVector zero() { + BitVector b = new BitVector(); + b.set(0); + return b; + } + + private BitVector one() { + BitVector b = new BitVector(); + b.set(1); + return b; + } + + public UnaryOperator getEdgeTransferFunction(String from, String to) { + if (from == nodes[1] && to == nodes[3]) + return new BitVectorFilter(zero()); + else if (from == nodes[1] && to == nodes[2]) + return new BitVectorFilter(one()); + else { + return BitVectorIdentity.instance(); + } + } + + public boolean hasEdgeTransferFunctions() { + return true; + } + + public AbstractMeetOperator getMeetOperator() { + return BitVectorUnion.instance(); + } + + }; + + BitVectorFramework F = new BitVectorFramework(G, functions, values); + DataflowSolver s = new BitVectorSolver(F); + s.solve(); + return result2String(s); + } + + public static String result2String(DataflowSolver solver) { + StringBuffer result = new StringBuffer("------\n"); + for (int i = 0; i < nodes.length; i++) { + String n = nodes[i]; + BitVectorVariable varI = (BitVectorVariable) solver.getOut(n); + String s = varI.toString(); + result.append("Node " + n + "(" + i + ") = " + s + "\n"); + } + return result.toString(); + } +} \ No newline at end of file diff --git a/com.ibm.wala.core.tests/src/com/ibm/wala/core/tests/basic/PrimitivesTest.java b/com.ibm.wala.core.tests/src/com/ibm/wala/core/tests/basic/PrimitivesTest.java new file mode 100644 index 000000000..3dbe937d4 --- /dev/null +++ b/com.ibm.wala.core.tests/src/com/ibm/wala/core/tests/basic/PrimitivesTest.java @@ -0,0 +1,585 @@ +/******************************************************************************* + * 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.core.tests.basic; + +import java.util.Collection; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import com.ibm.wala.core.tests.util.WalaTestCase; +import com.ibm.wala.util.collections.BimodalMap; +import com.ibm.wala.util.collections.Iterator2Collection; +import com.ibm.wala.util.collections.SmallMap; +import com.ibm.wala.util.graph.Dominators; +import com.ibm.wala.util.graph.Graph; +import com.ibm.wala.util.graph.NumberedGraph; +import com.ibm.wala.util.graph.impl.SlowSparseNumberedGraph; +import com.ibm.wala.util.graph.traverse.BFSPathFinder; +import com.ibm.wala.util.graph.traverse.BoundedBFSIterator; +import com.ibm.wala.util.intset.BasicNonNegativeIntRelation; +import com.ibm.wala.util.intset.BimodalMutableIntSetFactory; +import com.ibm.wala.util.intset.BitVector; +import com.ibm.wala.util.intset.BitVectorIntSetFactory; +import com.ibm.wala.util.intset.IBinaryNonNegativeIntRelation; +import com.ibm.wala.util.intset.IntPair; +import com.ibm.wala.util.intset.IntSet; +import com.ibm.wala.util.intset.IntSetUtil; +import com.ibm.wala.util.intset.IntegerUnionFind; +import com.ibm.wala.util.intset.MutableIntSet; +import com.ibm.wala.util.intset.MutableIntSetFactory; +import com.ibm.wala.util.intset.MutableSharedBitVectorIntSetFactory; +import com.ibm.wala.util.intset.MutableSparseIntSetFactory; +import com.ibm.wala.util.intset.SparseIntSet; + +/** + * + * JUnit tests for some primitive operations. + * + * @author sfink + */ +public class PrimitivesTest extends WalaTestCase { + + /** + * + */ + public PrimitivesTest() { + super("PrimitivesTest"); + } + + /** + * @param arg0 + */ + public PrimitivesTest(String arg0) { + super(arg0); + } + + /** + * Test the MutableSparseIntSet implementation + */ + private void doMutableIntSet(MutableIntSetFactory factory) { + MutableIntSet v = factory.parse("{9,17}"); + MutableIntSet w = factory.make(new int[] {}); + MutableIntSet x = factory.make(new int[] { 7, 4, 2, 4, 2, 2 }); + MutableIntSet y = factory.make(new int[] { 7, 7, 7, 2, 7, 1 }); + MutableIntSet z = factory.parse("{ 9 }"); + + System.out.println(w); // { } + System.out.println(x); // { 2 4 7 } + System.out.println(y); // { 1 2 7 } + System.out.println(z); // { 9 } + + MutableIntSet temp = factory.makeCopy(x); + temp.intersectWith(y); + System.out.println(temp); // { 2 7 } + temp.copySet(x); + temp.addAll(y); + System.out.println(temp); // { 1 2 4 7 } + temp.copySet(x); + System.out.println(IntSetUtil.diff(x, y, factory)); // { 4 } + System.out.println(IntSetUtil.diff(v, z, factory)); // { 17 } + System.out.println(IntSetUtil.diff(z, v, factory)); // { } + + // assertTrue(x.union(z).intersection(y.union(z)).equals(x.intersection(y).union(z))); + MutableIntSet temp1 = factory.makeCopy(x); + MutableIntSet temp2 = factory.makeCopy(x); + MutableIntSet tempY = factory.makeCopy(y); + temp1.addAll(z); + tempY.addAll(z); + temp1.intersectWith(tempY); + temp2.intersectWith(y); + temp2.addAll(z); + assertTrue(temp1.sameValue(temp2)); + + // assertTrue(x.union(z).diff(z).equals(x)); + assertTrue(w.isEmpty()); + assertTrue(IntSetUtil.diff(x, x, factory).isEmpty()); + assertTrue(IntSetUtil.diff(z, v, factory).isEmpty()); + assertTrue(IntSetUtil.diff(v, z, factory).sameValue(SparseIntSet.singleton(17))); + assertTrue(IntSetUtil.diff(z, v, factory).isEmpty()); + assertTrue(z.isSubset(v)); + temp = factory.make(); + temp.add(4); + System.out.println(temp); // { 4 } + temp.add(7); + System.out.println(temp); // { 4 7 } + temp.add(2); + System.out.println(temp); // { 2 4 7 } + System.out.println(x); // { 2 4 7 } + assertTrue(temp.sameValue(x)); + + MutableIntSet a = factory.parse("{1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31,33,35,37,39,41,43,45,47,49,51,53,55,57,59}"); + System.out.println(a); // { 1 3 5 7 9 11 13 15 17 19 21 23 25 27 29 31 33 + // 35 + // 37 39 41 43 45 47 49 51 53 55 57 59 } + assertTrue(a.sameValue(a)); + IntSet i = a.intersection(temp); + assertTrue(i.sameValue(SparseIntSet.singleton(7))); + a.add(100); + assertTrue(a.sameValue(a)); + + MutableIntSet b = factory.parse("{1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31,33,35,37,39,41,43,45,47,49,51,53,55,57,59,100}"); + assertTrue(a.sameValue(b)); + assertTrue(a.isSubset(b)); + + b = factory.makeCopy(a); + assertTrue(a.sameValue(b)); + b.remove(1); + b.add(0); + assertTrue(!a.sameValue(b)); + + a = factory.parse("{1}"); + assertFalse(a.isSubset(b)); + b.remove(0); + assertFalse(a.isSubset(b)); + a.remove(1); + assertTrue(a.isEmpty()); + i = a.intersection(temp); + assertTrue(a.isEmpty()); + + temp2 = factory.make(); + assertTrue(temp2.sameValue(a)); + + a = factory.parse("{2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32,34,36,38,40,42,44,46,48,50,51,53,55,57,59,61,63}"); + b = factory.parse("{2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32,34,36,38,40,42,44,46,48,50,52,54,56,58,60,62}"); + MutableIntSet c = factory.parse("{2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32,34,36,38,40,42,44,46,48,50}"); + MutableIntSet d = factory.parse("{2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32,34,36,38,40,42,44,46,48,50}"); + MutableIntSet e = factory.parse("{2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32,34}"); + + assertTrue(e.isSubset(d)); + e.addAll(d); + assertTrue(e.isSubset(d)); + e.remove(12); + assertTrue(e.isSubset(d)); + e.add(105); + assertFalse(e.isSubset(d)); + + assertFalse(b.isSubset(a)); + + b.add(53); + assertFalse(b.isSubset(a)); + + a.add(52); + a.remove(52); + assertFalse(b.isSubset(a)); + + c.add(55); + assertFalse(c.isSubset(b)); + + d.add(53); + assertTrue(d.isSubset(b)); + + d = factory.make(); + d.copySet(c); + assertFalse(d.isSubset(b)); + + a = factory.parse("{2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32,34,36,38,40,42,44,46,48,50}"); + b = factory.parse("{2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32,34,36,38,40,42,44,46,48}"); + assertFalse(a.sameValue(b)); + b.add(50); + assertTrue(a.sameValue(b)); + a.add(11); + b.add(11); + assertTrue(a.sameValue(b)); + + a = factory.parse("{2,4,6,8,10,12,14,16,18,20,50}"); + b = factory.parse("{24,26,28,30,32,34,36,38,40,42,44,46,48}"); + c = factory.parse("{2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32,34,36,38,40,42,44,46,48,50}"); + a.addAll(b); + a.add(22); + assertTrue(a.sameValue(c)); + + a = factory.parse("{2,4,6,8,10,12,14,16,18,20,50}"); + b = factory.parse("{24,26,28,30,32,34,36,38,40,42,44,46,48}"); + c = factory.parse("{2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32,34,36,38,40,42,44,46,48,50}"); + b.addAll(factory.parse("{22}")); + a.addAll(b); + assertTrue(a.sameValue(c)); + + a = factory.parse("{2,4,6,8,10,12,14,16,18,20}"); + b = factory.parse("{22,24,26,28,30,32,34,36,38,40,42,44,46,48}"); + c = factory.parse("{2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32,34,36,38,40,42,44,46,48,50}"); + c.remove(22); + a.addAll(b); + assertFalse(a.sameValue(c)); + + a = factory.parse("{1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31,33,35,37,39,41,43,45,47,49,51,53,55,57,59}"); + System.out.println(a); // { 1 3 5 7 9 11 13 15 17 19 21 23 25 27 29 31 33 + // 35 + // 37 39 41 43 45 47 49 51 53 55 57 59 } + assertTrue(a.sameValue(a)); + i = a.intersection(temp); + assertTrue(i.sameValue(SparseIntSet.singleton(7))); + a.add(100); + assertTrue(a.sameValue(a)); + + b = factory.parse("{1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31,33,35,37,39,41,43,45,47,49,51,53,55,57,59,100}"); + assertTrue(a.sameValue(b)); + assertTrue(a.isSubset(b)); + + b = factory.makeCopy(a); + assertTrue(a.sameValue(b)); + b.remove(1); + b.add(0); + assertTrue(!a.sameValue(b)); + + a = factory.parse("{1}"); + assertFalse(a.isSubset(b)); + b.remove(0); + assertFalse(a.isSubset(b)); + a.remove(1); + assertTrue(a.isEmpty()); + i = a.intersection(temp); + assertTrue(a.isEmpty()); + + temp2 = factory.make(); + assertTrue(temp2.sameValue(a)); + } + + /** + * Test the MutableSharedBitVectorIntSet implementation + */ + public void testMutableSharedBitVectorIntSet() { + doMutableIntSet(new MutableSharedBitVectorIntSetFactory()); + } + + /** + * Test the MutableSparseIntSet implementation + */ + public void testMutableSparseIntSet() { + doMutableIntSet(new MutableSparseIntSetFactory()); + } + + /** + * Test the BimodalMutableSparseIntSet implementation + */ + public void testBimodalMutableSparseIntSet() { + doMutableIntSet(new BimodalMutableIntSetFactory()); + } + + /** + * Test the BitVectorIntSet implementation + */ + public void testBitVectorIntSet() { + doMutableIntSet(new BitVectorIntSetFactory()); + } + + public void testSmallMap() { + SmallMap M = new SmallMap(); + Integer I1 = new Integer(1); + Integer I2 = new Integer(2); + Integer I3 = new Integer(3); + M.put(I1, I1); + M.put(I2, I2); + M.put(I3, I3); + + Integer I = (Integer) M.get(new Integer(2)); + assertTrue(I != null); + assertTrue(I.equals(I2)); + + I = (Integer) M.get(new Integer(4)); + assertTrue(I == null); + + I = (Integer) M.put(new Integer(2), new Integer(3)); + assertTrue(I.equals(I2)); + I = (Integer) M.get(I2); + assertTrue(I.equals(I3)); + } + + public void testBimodalMap() { + Map M = new BimodalMap(3); + Integer I1 = new Integer(1); + Integer I2 = new Integer(2); + Integer I3 = new Integer(3); + Integer I4 = new Integer(4); + Integer I5 = new Integer(5); + Integer I6 = new Integer(6); + M.put(I1, I1); + M.put(I2, I2); + M.put(I3, I3); + + Integer I = M.get(new Integer(2)); + assertTrue(I != null); + assertTrue(I.equals(I2)); + + I = M.get(new Integer(4)); + assertTrue(I == null); + + I = M.put(new Integer(2), new Integer(3)); + assertTrue(I.equals(I2)); + I = M.get(I2); + assertTrue(I.equals(I3)); + + M.put(I4, I4); + M.put(I5, I5); + M.put(I6, I6); + I = M.get(new Integer(4)); + assertTrue(I != null); + assertTrue(I.equals(I4)); + + I = M.get(new Integer(7)); + assertTrue(I == null); + + I = M.put(new Integer(2), new Integer(6)); + assertTrue(I.equals(I3)); + I = M.get(I2); + assertTrue(I.equals(I6)); + } + + public void testBFSPathFinder() { + NumberedGraph G = makeBFSTestGraph(); + + // path from 0 to 8 + BFSPathFinder pf = new BFSPathFinder(G, G.getNode(0), G.getNode(8)); + List p = pf.find(); + + // path should be 8, 6, 4, 2, 0 + System.out.println("Path is " + p); + for (int i = 0; i < p.size(); i++) { + assertTrue((p.get(i)).intValue() == new int[] { 8, 6, 4, 2, 0 }[i]); + } + } + + public void testBoundedBFS() { + NumberedGraph G = makeBFSTestGraph(); + + BoundedBFSIterator bfs = new BoundedBFSIterator(G, G.getNode(0), 0); + Collection c = new Iterator2Collection(bfs); + assertTrue(c.size() == 1); + + bfs = new BoundedBFSIterator(G, G.getNode(0), 1); + c = new Iterator2Collection(bfs); + assertTrue(c.size() == 3); + + bfs = new BoundedBFSIterator(G, G.getNode(0), 2); + c = new Iterator2Collection(bfs); + assertTrue(c.size() == 5); + + bfs = new BoundedBFSIterator(G, G.getNode(0), 3); + c = new Iterator2Collection(bfs); + assertTrue(c.size() == 7); + + bfs = new BoundedBFSIterator(G, G.getNode(0), 4); + c = new Iterator2Collection(bfs); + assertTrue(c.size() == 9); + + bfs = new BoundedBFSIterator(G, G.getNode(0), 5); + c = new Iterator2Collection(bfs); + assertTrue(c.size() == 10); + + bfs = new BoundedBFSIterator(G, G.getNode(0), 500); + c = new Iterator2Collection(bfs); + assertTrue(c.size() == 10); + } + + private NumberedGraph makeBFSTestGraph() { + // test graph + NumberedGraph G = new SlowSparseNumberedGraph(); + + // add 10 nodes + Integer[] nodes = new Integer[10]; + for (int i = 0; i < nodes.length; i++) + G.addNode(nodes[i] = new Integer(i)); + + // edges to i-1, i+1, i+2 + for (int i = 0; i < nodes.length; i++) { + if (i > 0) { + G.addEdge(nodes[i], nodes[i - 1]); + } + if (i < nodes.length - 1) { + G.addEdge(nodes[i], nodes[i + 1]); + if (i < nodes.length - 2) { + G.addEdge(nodes[i], nodes[i + 2]); + } + } + } + return G; + } + + public void testDominatorsA() { + // test graph + Graph G = new SlowSparseNumberedGraph(); + + // add nodes + Object[] nodes = new Object[11]; + for (int i = 0; i < nodes.length; i++) + G.addNode(nodes[i] = new Integer(i)); + + // add edges + G.addEdge(nodes[10], nodes[0]); + G.addEdge(nodes[10], nodes[1]); + G.addEdge(nodes[0], nodes[2]); + G.addEdge(nodes[1], nodes[3]); + G.addEdge(nodes[2], nodes[5]); + G.addEdge(nodes[3], nodes[5]); + G.addEdge(nodes[4], nodes[2]); + G.addEdge(nodes[5], nodes[8]); + G.addEdge(nodes[6], nodes[3]); + G.addEdge(nodes[7], nodes[4]); + G.addEdge(nodes[8], nodes[7]); + G.addEdge(nodes[8], nodes[9]); + G.addEdge(nodes[9], nodes[6]); + + // compute dominators + Dominators D = new Dominators(G, nodes[10]); + + // assertions + int i = 0; + Object[] desired4 = new Object[] { nodes[4], nodes[7], nodes[8], nodes[5], nodes[10] }; + for (Iterator d4 = D.dominators(nodes[4]); d4.hasNext();) + assertTrue(d4.next() == desired4[i++]); + + int j = 0; + Object[] desired5 = new Object[] { nodes[8] }; + for (Iterator t4 = D.dominatorTree().getSuccNodes(nodes[5]); t4.hasNext();) + assertTrue(t4.next() == desired5[j++]); + + assertTrue(D.dominatorTree().getSuccNodeCount(nodes[10]) == 5); + } + + public void testBinaryIntegerRelation() { + byte[] impl = new byte[] { BasicNonNegativeIntRelation.SIMPLE, BasicNonNegativeIntRelation.TWO_LEVEL, + BasicNonNegativeIntRelation.SIMPLE }; + IBinaryNonNegativeIntRelation R = new BasicNonNegativeIntRelation(impl, BasicNonNegativeIntRelation.TWO_LEVEL); + R.add(3, 5); + R.add(3, 7); + R.add(3, 9); + R.add(3, 11); + R.add(5, 1); + int count = 0; + for (Iterator it = R.iterator(); it.hasNext();) { + System.err.println(it.next()); + count++; + } + assertTrue(count == 5); + + IntSet x = R.getRelated(3); + assertTrue(x.size() == 4); + + x = R.getRelated(5); + assertTrue(x.size() == 1); + + R.remove(5, 1); + x = R.getRelated(5); + assertTrue(x == null); + + R.add(2, 1); + R.add(2, 2); + R.remove(2, 1); + x = R.getRelated(2); + assertTrue(x.size() == 1); + + R.removeAll(3); + x = R.getRelated(3); + assertTrue(x == null); + + x = R.getRelated(0); + assertTrue(x == null); + + for (int i = 0; i < 100; i++) { + R.add(1, i); + } + assertTrue(R.getRelated(1).size() == 100); + R.remove(1, 1); + assertTrue(R.getRelated(1).size() == 99); + } + + public void testUnionFind() { + int SIZE = 10000; + IntegerUnionFind uf = new IntegerUnionFind(SIZE); + int count = countEquivalenceClasses(uf); + assertTrue("Got count " + count, count == SIZE); + + uf.union(3, 7); + assertTrue(uf.find(3) == uf.find(7)); + assertTrue("Got uf.find(3)=" + uf.find(3), uf.find(3) == 3 || uf.find(3) == 7); + + uf.union(7, SIZE - 1); + assertTrue(uf.find(3) == uf.find(SIZE - 1)); + assertTrue("Got uf.find(3)=" + uf.find(3), uf.find(3) == 3 || uf.find(3) == 7 || uf.find(3) == SIZE - 1); + + for (int i = 0; i < SIZE - 1; i++) { + uf.union(i, i + 1); + } + count = countEquivalenceClasses(uf); + assertTrue("Got count " + count, count == 1); + + uf = new IntegerUnionFind(SIZE); + for (int i = 0; i < SIZE; i++) { + if ((i % 2) == 0) { + uf.union(i, 0); + } else { + uf.union(i, 1); + } + } + count = countEquivalenceClasses(uf); + assertTrue("Got count " + count, count == 2); + } + + private int countEquivalenceClasses(IntegerUnionFind uf) { + HashSet s = new HashSet(); + for (int i = 0; i < uf.size(); i++) { + s.add(new Integer(uf.find(i))); + } + return s.size(); + } + + public void testBitVectors() { + BitVector bv = new BitVector(); + + // does the following not automatically scale the bitvector to + // a reasonable size? + bv.set(55); + + assertTrue(bv.max() == 55); + assertTrue(bv.get(55)); + + bv.set(59); + assertTrue(bv.max() == 59); + assertTrue(bv.get(55)); + assertTrue(bv.get(59)); + + { + boolean[] gets = new boolean[] { false, true, true }; + int[] bits = new int[] { 0, 55, 59 }; + for (int i = 0, j = 0; i != -1; i = bv.nextSetBit(i + 1), j++) { + assertTrue(i == bits[j]); + assertTrue(bv.get(i) == gets[j]); + } + } + + bv.set(77); + + assertTrue(bv.max() == 77); + { + boolean[] gets = new boolean[] { false, true, true, true }; + int[] bits = new int[] { 0, 55, 59, 77 }; + for (int i = 0, j = 0; i != -1; i = bv.nextSetBit(i + 1), j++) { + assertTrue(i == bits[j]); + assertTrue(bv.get(i) == gets[j]); + } + } + + bv.set(3); + assertTrue(bv.max() == 77); + { + boolean[] gets = new boolean[] { false, true, true, true, true }; + int[] bits = new int[] { 0, 3, 55, 59, 77 }; + for (int i = 0, j = 0; i != -1; i = bv.nextSetBit(i + 1), j++) { + assertTrue(i == bits[j]); + assertTrue(bv.get(i) == gets[j]); + } + } + + System.out.println(bv); + } +} diff --git a/com.ibm.wala.core.tests/src/com/ibm/wala/core/tests/callGraph/CallGraphTest.java b/com.ibm.wala.core.tests/src/com/ibm/wala/core/tests/callGraph/CallGraphTest.java new file mode 100644 index 000000000..8fe18a260 --- /dev/null +++ b/com.ibm.wala.core.tests/src/com/ibm/wala/core/tests/callGraph/CallGraphTest.java @@ -0,0 +1,567 @@ +/******************************************************************************* + * Copyright (c) 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.core.tests.callGraph; + +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; + +import org.eclipse.emf.ecore.EObject; + +import com.ibm.wala.cfg.CFGCache; +import com.ibm.wala.cfg.IBasicBlock; +import com.ibm.wala.core.tests.util.TestConstants; +import com.ibm.wala.core.tests.util.WalaTestCase; +import com.ibm.wala.ecore.java.ECallSite; +import com.ibm.wala.ecore.java.EJavaMethod; +import com.ibm.wala.ecore.java.impl.JavaPackageImpl; +import com.ibm.wala.emf.wrappers.ECallGraphWrapper; +import com.ibm.wala.emf.wrappers.EMFBridge; +import com.ibm.wala.ipa.callgraph.AnalysisOptions; +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.CallGraphStats; +import com.ibm.wala.ipa.callgraph.Entrypoints; +import com.ibm.wala.ipa.callgraph.impl.AllApplicationEntrypoints; +import com.ibm.wala.ipa.callgraph.impl.Util; +import com.ibm.wala.ipa.cfg.BasicBlockInContext; +import com.ibm.wala.ipa.cfg.InterproceduralCFG; +import com.ibm.wala.ipa.cha.ClassHierarchy; +import com.ibm.wala.ipa.cha.ClassHierarchyException; +import com.ibm.wala.types.MethodReference; +import com.ibm.wala.util.collections.HashSetFactory; +import com.ibm.wala.util.debug.Assertions; +import com.ibm.wala.util.debug.Trace; +import com.ibm.wala.util.graph.Graph; +import com.ibm.wala.util.graph.GraphIntegrity; +import com.ibm.wala.util.graph.GraphIntegrity.UnsoundGraphException; +import com.ibm.wala.util.graph.traverse.DFS; +import com.ibm.wala.util.warnings.CallGraphWarnings; +import com.ibm.wala.util.warnings.WarningSet; + +/** + * + * Tests for Call Graph construction + * + * @author sfink + */ + +public class CallGraphTest extends WalaTestCase { + + static { + JavaPackageImpl.init(); + } + + private static final String[] IGNORE_STRINGS = { "finalize", "java.lang.ThreadLocal", "java.lang.ref.Reference.get()" }; + + public static void main(String[] args) { + justThisTest(CallGraphTest.class); + } + + /** + * Constructor for SpecJTest. + * + * @param arg0 + */ + public CallGraphTest(String arg0) { + super(arg0); + } + + /* + * public void testOpenccg() { AnalysisScope scope = + * CallGraphTestUtil.makeJ2SEAnalysisScope(Config.OPENCCG); WarningSet + * warnings = new WarningSet(); ClassHierarchy cha = + * ClassHierarchy.buildClassHierarchy(scope, warnings); Entrypoints + * entrypoints = + * com.ibm.wala.ipa.callgraph.impl.Util.makeMainEntrypoints(scope, cha, + * Config.OPENCCG_CROSS_VALIDATE_REALIZER); AnalysisOptions options = + * CallGraphTestUtil.makeAnalysisOptions(scope, entrypoints); + * + * Trace.println("OPENCCG Cross Validate Realizer set up warnings:\n"); + * Trace.print(warnings.toString()); + * + * doCallGraphs(options, cha, scope, null, useShortProfile(), false); } + * + * public void testKaba() { AnalysisScope scope = + * CallGraphTestUtil.makeJ2SEAnalysisScope(Config.KABA); WarningSet warnings = + * new WarningSet(); ClassHierarchy cha = + * ClassHierarchy.buildClassHierarchy(scope, warnings); Entrypoints + * entrypoints = + * com.ibm.wala.ipa.callgraph.impl.Util.makeMainEntrypoints(scope, cha, + * Config.KABA_MAIN); AnalysisOptions options = + * CallGraphTestUtil.makeAnalysisOptions(scope, entrypoints); + * + * Trace.println("kaba verifier set up warnings:\n"); + * Trace.print(warnings.toString()); + * + * doCallGraphs(options, cha, scope, null, useShortProfile(), false); } + * + * public void testAntlr() { AnalysisScope scope = + * CallGraphTestUtil.makeJ2SEAnalysisScope(Config.ANTLR); WarningSet warnings = + * new WarningSet(); ClassHierarchy cha = + * ClassHierarchy.buildClassHierarchy(scope, warnings); Entrypoints + * entrypoints = + * com.ibm.wala.ipa.callgraph.impl.Util.makeMainEntrypoints(scope, cha, + * Config.ANTLR_MAIN); AnalysisOptions options = + * CallGraphTestUtil.makeAnalysisOptions(scope, entrypoints); + * + * Trace.println("ANTLR verifier set up warnings:\n"); + * Trace.print(warnings.toString()); + * + * doCallGraphs(options, cha, scope, null, useShortProfile(), false); } + */ + + public void testBcelVerifier() throws ClassHierarchyException { + AnalysisScope scope = CallGraphTestUtil.makeJ2SEAnalysisScope(TestConstants.BCEL); + WarningSet warnings = new WarningSet(); + ClassHierarchy cha = ClassHierarchy.make(scope, warnings); + Entrypoints entrypoints = com.ibm.wala.ipa.callgraph.impl.Util + .makeMainEntrypoints(scope, cha, TestConstants.BCEL_VERIFIER_MAIN); + AnalysisOptions options = CallGraphTestUtil.makeAnalysisOptions(scope, entrypoints); + + Trace.println("bcel verifier set up warnings:\n"); + Trace.print(warnings.toString()); + + doCallGraphs(options, cha, scope, null, useShortProfile(), false); + } + + public void testJava_cup() throws ClassHierarchyException { + AnalysisScope scope = CallGraphTestUtil.makeJ2SEAnalysisScope(TestConstants.JAVA_CUP); + WarningSet warnings = new WarningSet(); + ClassHierarchy cha = ClassHierarchy.make(scope, warnings); + Entrypoints entrypoints = com.ibm.wala.ipa.callgraph.impl.Util.makeMainEntrypoints(scope, cha, TestConstants.JAVA_CUP_MAIN); + AnalysisOptions options = CallGraphTestUtil.makeAnalysisOptions(scope, entrypoints); + + Trace.println("java_cup set up warnings:\n"); + Trace.print(warnings.toString()); + + doCallGraphs(options, cha, scope, null, useShortProfile(), false); + } + + public void testJLex() throws ClassHierarchyException { + AnalysisScope scope = CallGraphTestUtil.makeJ2SEAnalysisScope(TestConstants.JLEX); + WarningSet warnings = new WarningSet(); + ClassHierarchy cha = ClassHierarchy.make(scope, warnings); + Entrypoints entrypoints = com.ibm.wala.ipa.callgraph.impl.Util.makeMainEntrypoints(scope, cha, TestConstants.JLEX_MAIN); + AnalysisOptions options = CallGraphTestUtil.makeAnalysisOptions(scope, entrypoints); + + Trace.println("JLex set up warnings:\n"); + Trace.print(warnings.toString()); + + doCallGraphs(options, cha, scope, null, useShortProfile(), false); + } + + public void testCornerCases() throws ClassHierarchyException { + AnalysisScope scope = CallGraphTestUtil.makeJ2SEAnalysisScope(TestConstants.WALA_TESTDATA); + WarningSet warnings = new WarningSet(); + ClassHierarchy cha = ClassHierarchy.make(scope, warnings); + Entrypoints entrypoints = new AllApplicationEntrypoints(scope, cha); + AnalysisOptions options = CallGraphTestUtil.makeAnalysisOptions(scope, entrypoints); + + Trace.println("testCornerCases set up warnings:\n"); + Trace.print(warnings.toString()); + + warnings = doCallGraphs(options, cha, scope, null, useShortProfile(), false); + + // we expect a warning or two about class Abstract1, which has no concrete + // subclasses + String ws = warnings.toString(); + assertTrue("failed to report a warning about Abstract1", ws.indexOf("cornerCases/Abstract1") > -1); + + // we do not expect a warning about class Abstract2, which has a concrete + // subclasses + assertTrue("reported a warning about Abstract2", ws.indexOf("cornerCases/Abstract2") == -1); + } + + // + // public void testSPECjvm98() { + // AnalysisScope scope = CGTUtils.makeJ2SEAnalysisScope(Config.SPECJVM); + // + // // temporary hack because 1.5 libraries still cause grief + // if (scope.isJava15Libraries()) { + // scope = CGTUtils.makeJ2EEAnalysisScope(Config.SPECJVM); + // } + // + // WarningSet warnings = new WarningSet(); + // ClassHierarchy cha = ClassHierarchy.buildClassHierarchy(scope, warnings); + // Entrypoints entrypoints = + // com.ibm.wala.ipa.callgraph.impl.Util.makeMainEntrypoints(scope, cha, + // Config.SPECJVM_MAIN); + // AnalysisOptions options = CGTUtils.makeAnalysisOptions(scope, entrypoints); + // + // Trace.println("SPECjvm98 set up warnings:\n"); + // Trace.print(warnings.toString()); + // + // doCallGraphs(options, cha, scope, Config.SPECJVM_DCG, false, false); + // } + // + public void testHello() throws ClassHierarchyException { + AnalysisScope scope = CallGraphTestUtil.makeJ2SEAnalysisScope(TestConstants.HELLO); + WarningSet warnings = new WarningSet(); + ClassHierarchy cha = ClassHierarchy.make(scope, warnings); + Entrypoints entrypoints = com.ibm.wala.ipa.callgraph.impl.Util.makeMainEntrypoints(scope, cha, TestConstants.HELLO_MAIN); + AnalysisOptions options = CallGraphTestUtil.makeAnalysisOptions(scope, entrypoints); + + Trace.println("hello set up warnings:\n"); + Trace.print(warnings.toString()); + + doCallGraphs(options, cha, scope, null, false, false); + } + + public void testRecursion() throws ClassHierarchyException { + AnalysisScope scope = CallGraphTestUtil.makeJ2SEAnalysisScope(TestConstants.WALA_TESTDATA); + WarningSet warnings = new WarningSet(); + ClassHierarchy cha = ClassHierarchy.make(scope, warnings); + Entrypoints entrypoints = com.ibm.wala.ipa.callgraph.impl.Util.makeMainEntrypoints(scope, cha, TestConstants.RECURSE_MAIN); + AnalysisOptions options = CallGraphTestUtil.makeAnalysisOptions(scope, entrypoints); + + Trace.println("testRecursion set up warnings:\n"); + Trace.print(warnings.toString()); + + doCallGraphs(options, cha, scope, null, useShortProfile(), false); + } + + public void testHelloAllEntrypoints() throws ClassHierarchyException { + AnalysisScope scope = CallGraphTestUtil.makeJ2SEAnalysisScope(TestConstants.HELLO); + WarningSet warnings = new WarningSet(); + ClassHierarchy cha = ClassHierarchy.make(scope, warnings); + Entrypoints entrypoints = new AllApplicationEntrypoints(scope, cha); + AnalysisOptions options = CallGraphTestUtil.makeAnalysisOptions(scope, entrypoints); + + Trace.println("hello all entrypoints set up warnings:\n"); + Trace.print(warnings.toString()); + + doCallGraphs(options, cha, scope, null, useShortProfile(), false); + } + + // + // public void testSPECjvm98AllEntrypoints() { + // AnalysisScope scope = CGTUtils.makeJ2SEAnalysisScope(Config.SPECJVM); + // WarningSet warnings = new WarningSet(); + // ClassHierarchy cha = ClassHierarchy.buildClassHierarchy(scope, warnings); + // Entrypoints entrypoints = new AllApplicationEntrypoints(scope, cha); + // AnalysisOptions options = CGTUtils.makeAnalysisOptions(scope, entrypoints); + // + // Trace.println("SPECjvm98 set up warnings:\n"); + // Trace.print(warnings.toString()); + // + // doCallGraphs(options, cha, scope, null, useShortProfile(), true); + // } + + /** + * TODO: refactor this to avoid excessive code bloat. + */ + public static WarningSet doCallGraphs(AnalysisOptions options, ClassHierarchy cha, AnalysisScope scope, String dcgFile, + boolean stopAfterZeroCFA, boolean stopAfterZeroContainerCFA) { + + // /////////////// + // // RTA ///// + // /////////////// + WarningSet warnings = new WarningSet(); + CallGraph cg = CallGraphTestUtil.buildRTA(options, cha, scope, warnings); + try { + GraphIntegrity.check(cg); + } catch (UnsoundGraphException e1) { + e1.printStackTrace(); + assertTrue(e1.getMessage(), false); + } + Set rtaMethods = CallGraphStats.collectMethods(cg); + Trace.println("RTA methods reached: " + rtaMethods.size()); + Trace.println(CallGraphStats.getStats(cg)); + Trace.println("RTA warnings:\n"); + warnings.addAll(CallGraphWarnings.getWarnings(cg)); + Trace.print(warnings.toString(cg)); + + // /////////////// + // // 0-CFA ///// + // /////////////// + warnings = new WarningSet(); + cg = CallGraphTestUtil.buildZeroCFA(options, cha, scope, warnings); + + // FIXME: annoying special cases caused by clone2assign mean using + // the rta graph for proper graph subset checking does not work. + // (note that all the other such checks do use proper graph subset) + Graph squashZero = checkCallGraph(warnings, cg, null, rtaMethods, "0-CFA"); + + // test Pretransitive 0-CFA + // not currently supported + // warnings = new WarningSet(); + // options.setUsePreTransitiveSolver(true); + // CallGraph cgP = CallGraphTestUtil.buildZeroCFA(options, cha, scope, + // warnings); + // options.setUsePreTransitiveSolver(false); + // Graph squashPT = checkCallGraph(warnings, cgP, squashZero, null, "Pre-T + // 1"); + // checkCallGraph(warnings, cg, squashPT, null, "Pre-T 2"); + + if (stopAfterZeroCFA) { + return warnings; + } + // /////////////// + // // 0-1-CFA /// + // /////////////// + warnings = new WarningSet(); + cg = CallGraphTestUtil.buildZeroOneCFA(options, cha, scope, warnings); + Graph squashZeroOne = checkCallGraph(warnings, cg, squashZero, null, "0-1-CFA"); + + // /////////////////////////////////////////////////// + // // 0-CFA augmented to disambiguate containers /// + // /////////////////////////////////////////////////// + warnings = new WarningSet(); + cg = CallGraphTestUtil.buildZeroContainerCFA(options, cha, scope, warnings); + Graph squashZeroContainer = checkCallGraph(warnings, cg, squashZero, null, "0-Container-CFA"); + + if (stopAfterZeroContainerCFA) + return warnings; + + // /////////////////////////////////////////////////// + // // 0-1-CFA augmented to disambiguate containers /// + // /////////////////////////////////////////////////// + warnings = new WarningSet(); + cg = CallGraphTestUtil.buildZeroOneContainerCFA(options, cha, scope, warnings); + checkCallGraph(warnings, cg, squashZeroContainer, null, "0-1-Container-CFA"); + checkCallGraph(warnings, cg, squashZeroOne, null, "0-1-Container-CFA"); + + if (dcgFile != null) { + checkAgainstDCG(cg, dcgFile); + } + + // test ICFG + checkICFG(cg, options.getCFGCache()); + return warnings; + // ///////////// + // // 1-CFA /// + // ///////////// + // warnings = new WarningSet(); + // cg = buildOneCFA(); + + } + + /** + * Check properties of the InterproceduralCFG + * + * @param cg + */ + private static void checkICFG(CallGraph cg, CFGCache cfgCache) { + InterproceduralCFG icfg = new InterproceduralCFG(cg, cfgCache, new WarningSet()); + + try { + GraphIntegrity.check(icfg); + } catch (UnsoundGraphException e) { + e.printStackTrace(); + assertTrue(false); + } + + // perform a little icfg exercise + int count = 0; + for (Iterator it = icfg.iterateNodes(); it.hasNext();) { + IBasicBlock bb = (IBasicBlock) it.next(); + if (icfg.hasCall((BasicBlockInContext) bb)) { + count++; + } + } + } + + /** + * Check that cg is a superset of the dynamic call graph encoded in the + * dcgFile + * + * @param cg + * @param dcgFile + */ + private static void checkAgainstDCG(CallGraph cg, String dcgFile) { + + Set synthLeaves = getSyntheticLeaves(cg); + + com.ibm.wala.emf.wrappers.ECallGraphWrapper subG = com.ibm.wala.emf.wrappers.ECallGraphWrapper.load(dcgFile, + CallGraphTest.class.getClassLoader()); + com.ibm.wala.emf.wrappers.ECallGraphWrapper superG = EMFBridge.makeCallGraph(cg); + + prune(subG, synthLeaves); + prune(superG, synthLeaves); + + checkGraphSubset(superG, subG); + } + + /** + * @param superG + * @param subG + */ + public static void checkGraphSubset(ECallGraphWrapper superG, ECallGraphWrapper subG) { + Set nodeDiff = Util.setify(subG.iterateNodes()); + nodeDiff.removeAll(Util.setify(superG.iterateNodes())); + Set toRemove = HashSetFactory.make(); + for (Iterator it = nodeDiff.iterator(); it.hasNext();) { + EObject o = it.next(); + if (o instanceof ECallSite) { + toRemove.add(o); + } + } + // a bogus hack: ignore some stuff in the dcg that we haven't + // cleaned out; TODO: figure out what's happening and delete this + outer: for (Iterator it = nodeDiff.iterator(); it.hasNext();) { + EObject o = it.next(); + for (int i = 0; i < IGNORE_STRINGS.length; i++) { + if (o.toString().indexOf(IGNORE_STRINGS[i]) > -1) { + toRemove.add(o); + continue outer; + } + } + } + nodeDiff.removeAll(toRemove); + + if (!nodeDiff.isEmpty()) { + Trace.println("supergraph: "); + Trace.println(superG.toString()); + Trace.println("subgraph: "); + Trace.println(subG.toString()); + Trace.println("nodeDiff: "); + for (Iterator it = nodeDiff.iterator(); it.hasNext();) { + Trace.println(it.next().toString()); + } + Assertions.productionAssertion(nodeDiff.isEmpty(), "bad superset, see tracefile\n"); + } + } + + /** + *
                  + *
                • remove all methods from G that correspond to synthetic methods + *
                • remove all nodes from G that are no longer reachable from the fake + * root. + *
                    + * + * @param G + * an EMF format call graph + * @param synthetic + * a set of synthetic methods + */ + private static void prune(ECallGraphWrapper G, Set synthetic) { + // compute synthetic nodes + Set toRemove = HashSetFactory.make(); + for (Iterator it = synthetic.iterator(); it.hasNext();) { + CGNode n = it.next(); + EJavaMethod node = EMFBridge.makeJavaMethod(n.getMethod().getReference()); + if (node != null) { + toRemove.add(node); + } + } + + removeNodes(G, toRemove); + + // compute nodes reachable from the fake root + EJavaMethod fakeRoot = EMFBridge.makeFakeRootMethod(); + Assertions._assert(fakeRoot != null); + Collection c = DFS.getReachableNodes(G, Collections.singleton(fakeRoot)); + + // remove other nodes + toRemove = HashSetFactory.make(); + for (Iterator it = G.iterateNodes(); it.hasNext();) { + EObject n = it.next(); + if (!c.contains(n)) { + toRemove.add(n); + } + } + removeNodes(G, toRemove); + + // remove call site nodes with no targets (these won't appear in the dcg) + toRemove = HashSetFactory.make(); + for (Iterator it = G.iterateNodes(); it.hasNext();) { + EObject n = it.next(); + if (n instanceof ECallSite) { + if (G.getSuccNodeCount(n) == 0) { + toRemove.add(n); + } + } + } + removeNodes(G, toRemove); + + } + + /** + * @param G + * @param toRemove + */ + private static void removeNodes(ECallGraphWrapper G, Set toRemove) { + // remove all these nodes + for (Iterator it = toRemove.iterator(); it.hasNext();) { + EObject n = it.next(); + if (G.containsNode(n)) { + G.removeNodeAndEdges(n); + } + } + } + + /** + * @param cg + * @return Set in cg that are synthetic and have no call sites + */ + private static Set getSyntheticLeaves(CallGraph cg) { + HashSet result = HashSetFactory.make(); + for (Iterator it = cg.iterateNodes(); it.hasNext();) { + CGNode node = (CGNode) it.next(); + if (!node.equals(cg.getFakeRootNode())) { + if (node.getMethod().isSynthetic()) { + if (!node.iterateSites().hasNext()) { + result.add(node); + } + } + } + } + return result; + } + + /** + * Check consistency of a callgraph, and check that this call graph is a + * subset of a super-graph + * + * @param warnings + * object to track warnings + * @param cg + * @param superCG + * @param superMethods + * @param thisAlgorithm + * @return a squashed version of cg + */ + private static Graph checkCallGraph(WarningSet warnings, CallGraph cg, Graph superCG, + Set superMethods, String thisAlgorithm) { + try { + GraphIntegrity.check(cg); + } catch (UnsoundGraphException e1) { + assertTrue(e1.getMessage(), false); + } + Set callGraphMethods = CallGraphStats.collectMethods(cg); + Trace.println(thisAlgorithm + " methods reached: " + callGraphMethods.size()); + Trace.println(CallGraphStats.getStats(cg)); + Trace.println(thisAlgorithm + " warnings:\n"); + warnings.addAll(CallGraphWarnings.getWarnings(cg)); + Trace.print(warnings.toString(cg)); + + Graph thisCG = com.ibm.wala.ipa.callgraph.impl.Util.squashCallGraph(thisAlgorithm, cg); + + if (superCG != null) { + com.ibm.wala.ipa.callgraph.impl.Util.checkGraphSubset(superCG, thisCG); + } else { + if (!superMethods.containsAll(callGraphMethods)) { + Set temp = HashSetFactory.make(); + temp.addAll(callGraphMethods); + temp.removeAll(superMethods); + Trace.printCollection("Violations", temp); + Assertions.UNREACHABLE(); + } + } + + return thisCG; + } + +} diff --git a/com.ibm.wala.core.tests/src/com/ibm/wala/core/tests/callGraph/CallGraphTestUtil.java b/com.ibm.wala.core.tests/src/com/ibm/wala/core/tests/callGraph/CallGraphTestUtil.java new file mode 100644 index 000000000..2122fdb53 --- /dev/null +++ b/com.ibm.wala.core.tests/src/com/ibm/wala/core/tests/callGraph/CallGraphTestUtil.java @@ -0,0 +1,141 @@ +/******************************************************************************* + * 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.core.tests.callGraph; + +import com.ibm.wala.emf.wrappers.EMFScopeWrapper; +import com.ibm.wala.ipa.callgraph.AnalysisOptions; +import com.ibm.wala.ipa.callgraph.AnalysisScope; +import com.ibm.wala.ipa.callgraph.CallGraph; +import com.ibm.wala.ipa.callgraph.CallGraphBuilder; +import com.ibm.wala.ipa.callgraph.Entrypoints; +import com.ibm.wala.ipa.callgraph.impl.Util; +import com.ibm.wala.ipa.cha.ClassHierarchy; +import com.ibm.wala.util.Stopwatch; +import com.ibm.wala.util.debug.Trace; +import com.ibm.wala.util.warnings.WarningSet; + +/** + * + * Utilities for call graph tests + * + * @author sfink + */ +public class CallGraphTestUtil { + + private static final ClassLoader MY_CLASSLOADER = CallGraphTestUtil.class.getClassLoader(); + +// private static final String reflectionFile = Config.SPECJVM_REFLECTION; + + public static AnalysisOptions makeAnalysisOptions(AnalysisScope scope, Entrypoints entrypoints) { + AnalysisOptions options = new AnalysisOptions(scope, entrypoints); + +// InputStream rStream = CallGraphTestUtil.class.getClassLoader().getResourceAsStream(reflectionFile); +// ReflectionSpecification R = new XMLReflectionReader(rStream, scope); +// options.setReflectionSpec(R); + return options; + } + + + public static AnalysisScope makeJ2SEAnalysisScope(String scopeFile) { + return new EMFScopeWrapper(scopeFile, "J2SEClassHierarchyExclusions.xml", MY_CLASSLOADER); + } + + public static AnalysisScope makeJ2SEAnalysisScope(String scopeFile, String exclusionsFile) { + return new EMFScopeWrapper(scopeFile, exclusionsFile, MY_CLASSLOADER); + } + + public static CallGraph buildRTA(AnalysisOptions options, ClassHierarchy cha, AnalysisScope scope, WarningSet warnings) { + Stopwatch S = new Stopwatch("build RTA graph"); + S.start(); + + CallGraphBuilder builder = Util.makeRTABuilder(options, cha, scope, warnings); + CallGraph cg = builder.makeCallGraph(options); + + S.stop(); + Trace.println(S.report()); + return cg; + } + + public static CallGraph buildZeroCFA(AnalysisOptions options, ClassHierarchy cha, AnalysisScope scope, WarningSet warnings) { + Stopwatch S = new Stopwatch("build ZeroCFA graph"); + S.start(); + + CallGraphBuilder builder = Util.makeZeroCFABuilder(options, cha, scope, warnings); + CallGraph cg = builder.makeCallGraph(options); + + S.stop(); + Trace.println(S.report()); + return cg; + } + + public static CallGraph buildVanillaZeroOneCFA(AnalysisOptions options, ClassHierarchy cha, AnalysisScope scope, WarningSet warnings) { + Stopwatch S = new Stopwatch("build Vanila 0-1-CFA graph"); + S.start(); + + CallGraphBuilder builder = Util.makeVanillaZeroOneCFABuilder(options, cha, scope, warnings); + CallGraph cg = builder.makeCallGraph(options); + + S.stop(); + Trace.println(S.report()); + return cg; + } + + public static CallGraph buildZeroOneCFA(AnalysisOptions options, ClassHierarchy cha, AnalysisScope scope, WarningSet warnings) { + Stopwatch S = new Stopwatch("build 0-1-CFA graph"); + S.start(); + + CallGraphBuilder builder = Util.makeZeroOneCFABuilder(options, cha, scope, warnings); + CallGraph cg = builder.makeCallGraph(options); + + S.stop(); + Trace.println(S.report()); + return cg; + } + + public static CallGraph buildZeroContainerCFA(AnalysisOptions options, ClassHierarchy cha, AnalysisScope scope, + WarningSet warnings) { + Stopwatch S = new Stopwatch("build 0-1-Container-CFA graph"); + S.start(); + + CallGraphBuilder builder = Util.makeZeroContainerCFABuilder(options, cha, scope, warnings); + CallGraph cg = builder.makeCallGraph(options); + + S.stop(); + Trace.println(S.report()); + return cg; + } + + public static CallGraph buildZeroOneContainerCFA(AnalysisOptions options, ClassHierarchy cha, AnalysisScope scope, + WarningSet warnings) { + Stopwatch S = new Stopwatch("build 0-1-Container-CFA graph"); + S.start(); + + CallGraphBuilder builder = Util.makeZeroOneContainerCFABuilder(options, cha, scope, warnings); + CallGraph cg = builder.makeCallGraph(options); + + S.stop(); + Trace.println(S.report()); + return cg; + } + + public static CallGraph buildOneCFA(AnalysisOptions options, ClassHierarchy cha, AnalysisScope scope, WarningSet warnings) { + Stopwatch S = new Stopwatch("build 1-CFA graph"); + S.start(); + + CallGraphBuilder builder = Util.makeOneCFABuilder(options, cha, MY_CLASSLOADER, scope, warnings); + CallGraph cg = builder.makeCallGraph(options); + + S.stop(); + Trace.println(S.report()); + return cg; + } + +} diff --git a/com.ibm.wala.core.tests/src/com/ibm/wala/core/tests/callGraph/ClassConstantTest.java b/com.ibm.wala.core.tests/src/com/ibm/wala/core/tests/callGraph/ClassConstantTest.java new file mode 100644 index 000000000..c6486d19a --- /dev/null +++ b/com.ibm.wala.core.tests/src/com/ibm/wala/core/tests/callGraph/ClassConstantTest.java @@ -0,0 +1,77 @@ +/******************************************************************************* + * 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.core.tests.callGraph; + +import java.util.Set; + +import junit.framework.Assert; + +import com.ibm.wala.core.tests.util.TestConstants; +import com.ibm.wala.core.tests.util.WalaTestCase; +import com.ibm.wala.ipa.callgraph.AnalysisOptions; +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.Entrypoints; +import com.ibm.wala.ipa.callgraph.impl.Util; +import com.ibm.wala.ipa.cha.ClassHierarchy; +import com.ibm.wala.ipa.cha.ClassHierarchyException; +import com.ibm.wala.types.ClassLoaderReference; +import com.ibm.wala.types.MethodReference; +import com.ibm.wala.types.TypeReference; +import com.ibm.wala.util.debug.Trace; +import com.ibm.wala.util.warnings.WarningSet; + +/** + * Check handling of class constants (test for part of 1.5 support) + * + * @author Julian Dolby (dolby@us.ibm.com) + */ +public class ClassConstantTest extends WalaTestCase { + + public void testClassConstants() throws ClassHierarchyException { + + AnalysisScope scope = CallGraphTestUtil.makeJ2SEAnalysisScope(TestConstants.WALA_TESTDATA); + WarningSet warnings = new WarningSet(); + ClassHierarchy cha = ClassHierarchy.make(scope, warnings); + Trace.println("setup warnings:"); + Trace.println(warnings); + + // make sure we have the test class + TypeReference mainClassRef = TypeReference.findOrCreate(ClassLoaderReference.Application, TestConstants.CLASSCONSTANT_MAIN); + Assert.assertTrue(cha.lookupClass(mainClassRef) != null); + + // make call graph + Entrypoints entrypoints = Util.makeMainEntrypoints(scope, cha, TestConstants.CLASSCONSTANT_MAIN); + AnalysisOptions options = CallGraphTestUtil.makeAnalysisOptions(scope, entrypoints); + CallGraph cg = CallGraphTestUtil.buildZeroCFA(options, cha, scope, warnings); + Trace.println("\nCall graph:"); + Trace.println(cg); + + // make sure the main method is reached + MethodReference mainMethodRef = MethodReference.findOrCreate(mainClassRef, "main", "([Ljava/lang/String;)V"); + Set mainMethodNodes = cg.getNodes(mainMethodRef); + Assert.assertFalse(mainMethodNodes.isEmpty()); + CGNode mainMethodNode = (CGNode) mainMethodNodes.iterator().next(); + Trace.println("main IR:"); + Trace.println(cg.getInterpreter(mainMethodNode).getIR(mainMethodNode, warnings)); + + // Make sure call to hashCode is there (it uses the class constant) + TypeReference classRef = TypeReference.findOrCreate(ClassLoaderReference.Primordial, "Ljava/lang/Class"); + MethodReference hashCodeRef = MethodReference.findOrCreate(classRef, "hashCode", "()I"); + Set hashCodeNodes = cg.getNodes(hashCodeRef); + Assert.assertFalse(hashCodeNodes.isEmpty()); + + // make sure call to hashCode from main + Assert.assertTrue(cg.hasEdge(mainMethodNode, hashCodeNodes.iterator().next())); + } + +} diff --git a/com.ibm.wala.core.tests/src/com/ibm/wala/core/tests/callGraph/CloneTest.java b/com.ibm.wala.core.tests/src/com/ibm/wala/core/tests/callGraph/CloneTest.java new file mode 100644 index 000000000..0fddc56ae --- /dev/null +++ b/com.ibm.wala.core.tests/src/com/ibm/wala/core/tests/callGraph/CloneTest.java @@ -0,0 +1,72 @@ +/******************************************************************************* + * Copyright (c) 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.core.tests.callGraph; + +import java.util.Iterator; +import java.util.Set; + +import com.ibm.wala.classLoader.CallSiteReference; +import com.ibm.wala.core.tests.util.TestConstants; +import com.ibm.wala.core.tests.util.WalaTestCase; +import com.ibm.wala.ipa.callgraph.AnalysisOptions; +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.Entrypoints; +import com.ibm.wala.ipa.callgraph.impl.AllApplicationEntrypoints; +import com.ibm.wala.ipa.cha.ClassHierarchy; +import com.ibm.wala.ipa.cha.ClassHierarchyException; +import com.ibm.wala.types.ClassLoaderReference; +import com.ibm.wala.types.MethodReference; +import com.ibm.wala.types.TypeReference; +import com.ibm.wala.util.warnings.WarningSet; + +/** + * Check properties of a call to clone() in RTA + * + * @author Bruno Dufour + */ +public class CloneTest extends WalaTestCase { + + public void testClone() throws ClassHierarchyException { + + AnalysisScope scope = CallGraphTestUtil.makeJ2SEAnalysisScope(TestConstants.WALA_TESTDATA); + WarningSet warnings = new WarningSet(); + ClassHierarchy cha = ClassHierarchy.make(scope, warnings); + Entrypoints entrypoints = new AllApplicationEntrypoints(scope, cha); + AnalysisOptions options = CallGraphTestUtil.makeAnalysisOptions(scope, entrypoints); + + CallGraph cg = CallGraphTestUtil.buildRTA(options, cha, scope, warnings); + + // Find node corresp. to java.text.MessageFormat.clone() + TypeReference t = TypeReference.findOrCreate(ClassLoaderReference.Primordial, "Ljava/text/MessageFormat"); + MethodReference m = MethodReference.findOrCreate(t, "clone", "()Ljava/lang/Object;"); + CGNode node = (CGNode) cg.getNodes(m).iterator().next(); + + // Check there's exactly one target for each super call in + // MessageFormat.clone() + for (Iterator i = node.iterateSites(); i.hasNext();) { + CallSiteReference site = (CallSiteReference) i.next(); + if (site.isSpecial()) { + if (site.getDeclaredTarget().getDeclaringClass().equals(TypeReference.JavaLangObject)) { + Set targets = node.getPossibleTargets(site); + if (targets.size() != 1) { + System.err.println(targets.size() + " targets found for " + site); + for (Iterator k = targets.iterator(); k.hasNext();) { + System.err.println(" " + k.next()); + } + fail("found " + targets.size() + " targets for " + site + " in " + node); + } + } + } + } + } +} diff --git a/com.ibm.wala.core.tests/src/com/ibm/wala/core/tests/callGraph/CompareCDGTest.java b/com.ibm.wala.core.tests/src/com/ibm/wala/core/tests/callGraph/CompareCDGTest.java new file mode 100644 index 000000000..4e247de64 --- /dev/null +++ b/com.ibm.wala.core.tests/src/com/ibm/wala/core/tests/callGraph/CompareCDGTest.java @@ -0,0 +1,433 @@ +/******************************************************************************* + * Copyright (c) 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.core.tests.callGraph; + +import java.util.Iterator; +import java.util.Set; +import java.util.Vector; + +import com.ibm.wala.cfg.IBasicBlock; +import com.ibm.wala.cfg.cdg.BVControlDependenceGraph; +import com.ibm.wala.cfg.cdg.ControlDependenceGraph; +import com.ibm.wala.core.tests.util.TestConstants; +import com.ibm.wala.core.tests.util.WalaTestCase; +import com.ibm.wala.ecore.java.scope.EJavaAnalysisScope; +import com.ibm.wala.emf.wrappers.EMFScopeWrapper; +import com.ibm.wala.emf.wrappers.JavaScopeUtil; +import com.ibm.wala.ipa.callgraph.AnalysisOptions; +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.CallGraphStats; +import com.ibm.wala.ipa.callgraph.Entrypoints; +import com.ibm.wala.ipa.callgraph.impl.Util; +import com.ibm.wala.ipa.callgraph.propagation.cfa.CFABuilder; +import com.ibm.wala.ipa.cha.ClassHierarchy; +import com.ibm.wala.ipa.cha.ClassHierarchyException; +import com.ibm.wala.shrikeBT.IInstruction; +import com.ibm.wala.ssa.IR; +import com.ibm.wala.ssa.SSACFG; +import com.ibm.wala.ssa.SSAInstruction; +import com.ibm.wala.ssa.SSACFG.BasicBlock; +import com.ibm.wala.types.MethodReference; +import com.ibm.wala.util.debug.Assertions; +import com.ibm.wala.util.debug.Trace; +import com.ibm.wala.util.warnings.WalaException; +import com.ibm.wala.util.warnings.WarningSet; +import com.ibm.wala.viz.DotUtil; + +/** + * @author Mangala Gowri Nanda (minor hacks by Julian Dolby (dolby@us.ibm.com) + * to fit into domo junit test framework) + * + */ +public class CompareCDGTest extends WalaTestCase { + + /** + * Usage: CompareCDGTest + * + * The "jar file name" should be something like "/tmp/testdata/java_cup.jar" + * + * @param args + */ + public static void main(String[] args) { + run(args); + } + + /** + * Usage: args = "-appJar [jar file name] " The "jar file name" should be + * something like "/tmp/testdata/java_cup.jar" + * + * @param args + */ + public static void run(String[] args) { + try { + run(buildCallGraphCommandLine(args[0])); + } catch (WalaException e) { + Trace.println(e); + } + } + + public static void run(CallGraph g) { + compareCDGs(g); + Trace.println(CallGraphStats.getStats(g)); + } + + private static void compareCDGs(CallGraph g) { + long cdgTime = 0; + long bvTime = 0; + String dotExe = "dot"; + for (Iterator it = g.iterateNodes(); it.hasNext();) { + CGNode n = (CGNode) it.next(); + MethodReference mref = n.getMethod().getReference(); + Trace.println(mref.toString()); + // if(app.equals("Application")) + { + IR ir = g.getInterpreter(n).getIR(n, new WarningSet()); + if (ir != null) { + SSACFG cfg = ir.getControlFlowGraph(); + long startTime = System.currentTimeMillis(); + ControlDependenceGraph cdg = new ControlDependenceGraph(cfg, true); + long diff = System.currentTimeMillis() - startTime; + cdgTime += diff; + + startTime = System.currentTimeMillis(); + BVControlDependenceGraph bvcdg = new BVControlDependenceGraph(cfg); + diff = System.currentTimeMillis() - startTime; + bvTime += diff; + + if (!compatible(cfg, cdg, bvcdg)) { + Trace.println("\tMISMATCH!!"); + Vector vec = checkCFG(cfg, mref); + if (vec != null) { + Trace.println(mref + " has " + vec.size() + " blocks with no predecessors"); + } + + Trace.println("\nControlDependenceGraph output::"); + dumpCDGInfo(cfg, cdg); + Trace.println("\nBitVector ControlDependenceGraph output::"); + dumpCDGInfo(cfg, bvcdg); + Trace.println(""); + + String dotFile = "tmp.dot"; + String psFile = mref.getName() + ".cdg.ps"; + try { + DotUtil.dotify(cdg, null, dotFile, psFile, dotExe); + } catch (WalaException e) { + e.printStackTrace(); + } + + psFile = mref.getName() + ".bv.ps"; + try { + DotUtil.dotify(bvcdg, null, dotFile, psFile, dotExe); + } catch (WalaException e) { + e.printStackTrace(); + } + + Assertions.UNREACHABLE(); + } + } + } + } + Trace.println("Time to compute ControlDependenceGraph=" + cdgTime); + Trace.println("Time to compute BVControlDependenceGraph=" + bvTime); + } + + private static boolean compatible(SSACFG cfg, ControlDependenceGraph cdg, BVControlDependenceGraph bv) { + boolean ret = true; + for (Iterator it = cfg.iterateNodes(); it.hasNext();) { + SSACFG.BasicBlock ibb = (SSACFG.BasicBlock) it.next(); + int cCount = cdg.getPredNodeCount(ibb); + int bCount = bv.getPredNodeCount(ibb); + if (cCount != bCount) { + Trace.println("\tPred Count mismatch for " + ibb); + ret = false; + } + Iterator cdit = cdg.getPredNodes(ibb); + while (cdit.hasNext()) { + SSACFG.BasicBlock cdgbb = (SSACFG.BasicBlock) cdit.next(); + if (!bv.hasEdge(cdgbb, ibb)) { + Trace.println("\tPred " + cdgbb + " mismatch for " + ibb); + ret = false; + } + Set clabels = cdg.getEdgeLabels(cdgbb, ibb); + Set blabels = bv.getEdgeLabels(cdgbb, ibb); + Iterator labit = clabels.iterator(); + while (labit.hasNext()) { + Object lab = labit.next(); + if (!blabels.contains(lab)) { + Trace.println("\tLabel " + lab + " missing at " + cdgbb + " --> " + ibb); + ret = false; + } + } + } + + cCount = cdg.getSuccNodeCount(ibb); + bCount = bv.getSuccNodeCount(ibb); + if (cCount != bCount) { + Trace.println("\tSucc Count mismatch for " + ibb); + ret = false; + } + cdit = cdg.getSuccNodes(ibb); + while (cdit.hasNext()) { + SSACFG.BasicBlock cdgbb = (SSACFG.BasicBlock) cdit.next(); + if (!bv.hasEdge(ibb, cdgbb)) { + Trace.println("\tSucc " + cdgbb + " mismatch for " + ibb); + ret = false; + } + Set clabels = cdg.getEdgeLabels(ibb, cdgbb); + Set blabels = bv.getEdgeLabels(ibb, cdgbb); + Iterator labit = clabels.iterator(); + while (labit.hasNext()) { + Object lab = labit.next(); + if (!blabels.contains(lab)) { + Trace.println("\tLabel " + lab + " missing at " + ibb + " --> " + cdgbb); + ret = false; + } + } + } + + } + return ret; + } + + private static void dumpCDGInfo(SSACFG cfg, ControlDependenceGraph cdg) { + Trace.println("{\n"); + Vector seen = new Vector(); + SSACFG.BasicBlock entry = (SSACFG.BasicBlock) cfg.entry(); + Vector worklist = new Vector(); + worklist.add(entry); + while (worklist.size() > 0) { + SSACFG.BasicBlock ibb = worklist.remove(worklist.size() - 1); + if (seen.contains(ibb)) + continue; + seen.add(ibb); + + int number = ibb.getNumber(); + Trace.print("\n\tBB ID:" + number + "::" + ibb + " (CD="); + Iterator cdit = cdg.getPredNodes(ibb); + while (cdit.hasNext()) { + SSACFG.BasicBlock cdgbb = (SSACFG.BasicBlock) cdit.next(); + Trace.print(cdgbb.getNumber() + "["); + Set labels = cdg.getEdgeLabels(cdgbb, ibb); + Iterator labit = labels.iterator(); + while (labit.hasNext()) { + Object lab = labit.next(); + Trace.print(lab + ","); + } + Trace.print("] "); + } + Trace.print(")"); + + Iterator succ = cfg.getSuccNodes(ibb); + Trace.print(" (SUCC="); + while (succ.hasNext()) { + SSACFG.BasicBlock isc = (SSACFG.BasicBlock) succ.next(); + Trace.print(isc.getNumber() + ", "); + worklist.add(isc); + } + Trace.print(")"); + + Iterator pred = cfg.getPredNodes(ibb); + Trace.print(" (PRED="); + while (pred.hasNext()) { + SSACFG.BasicBlock isc = (SSACFG.BasicBlock) pred.next(); + Trace.print(isc.getNumber() + ", "); + } + Trace.println(") {"); + + Iterator it = ibb.iterateAllInstructions(); + int j = 0; + while (it.hasNext()) { + SSAInstruction inst = (SSAInstruction) it.next(); + if (inst != null) { + Trace.println("\t\t" + j++ + ":" + inst.toString()); + } + } + Trace.println("\t}\n"); + } + Trace.println("}\n"); + } + + private static void dumpCDGInfo(SSACFG cfg, BVControlDependenceGraph cdg) { + Trace.println("{\n"); + Vector seen = new Vector(); + SSACFG.BasicBlock entry = (SSACFG.BasicBlock) cfg.entry(); + Vector worklist = new Vector(); + worklist.add(entry); + while (worklist.size() > 0) { + SSACFG.BasicBlock ibb = worklist.remove(worklist.size() - 1); + if (seen.contains(ibb)) + continue; + seen.add(ibb); + + int number = ibb.getNumber(); + Trace.print("\n\tBB ID:" + number + "::" + ibb + " (CD="); + Iterator cdit = cdg.getPredNodes(ibb); + while (cdit.hasNext()) { + SSACFG.BasicBlock cdgbb = (SSACFG.BasicBlock) cdit.next(); + Trace.print(cdgbb.getNumber() + "["); + Set labels = cdg.getEdgeLabels(cdgbb, ibb); + Iterator labit = labels.iterator(); + while (labit.hasNext()) { + Object lab = labit.next(); + Trace.print(lab + ","); + } + Trace.print("] "); + } + Trace.print(")"); + + Iterator succ = cfg.getSuccNodes(ibb); + Trace.print(" (SUCC="); + while (succ.hasNext()) { + SSACFG.BasicBlock isc = (SSACFG.BasicBlock) succ.next(); + Trace.print(isc.getNumber() + ", "); + worklist.add(isc); + } + Trace.print(")"); + + Iterator pred = cfg.getPredNodes(ibb); + Trace.print(" (PRED="); + while (pred.hasNext()) { + SSACFG.BasicBlock isc = (SSACFG.BasicBlock) pred.next(); + Trace.print(isc.getNumber() + ", "); + } + Trace.println(") {"); + + Iterator it = ibb.iterateAllInstructions(); + int j = 0; + while (it.hasNext()) { + SSAInstruction inst = (SSAInstruction) it.next(); + if (inst != null) { + Trace.println("\t\t" + j++ + ":" + inst.toString()); + } + } + Trace.println("\t}\n"); + } + Trace.println("}\n"); + } + + /* + * private static void buildUncheckedCDGs(CallGraph g) { String dotExe = + * "dot"; int count = 0; for (Iterator it = g.iterateNodes(); it.hasNext();) { + * count++; CGNode n = (CGNode) it.next(); MethodReference mref = + * n.getMethod().getReference(); IR ir = ((SSAContextInterpreter) + * g.getInterpreter(n)).getIR(n, new WarningSet()); if (ir != null) { SSACFG + * cfg = ir.getControlFlowGraph(); Vector vec = checkCFG(cfg, mref); if ( vec != + * null ) { // Trace.println(mref.toString()); ControlDependenceGraph cdg = + * new ControlDependenceGraph(cfg,true); boolean found = false; for ( int i=0; + * i0 ) { found = true; break; } } if ( !found ) + * continue; + * + * Trace.println(mref+" has "+vec.size()+ " blocks with no predecessors"); for ( + * int i=0 ; i checkCFG(SSACFG cfg, MethodReference mref) { + Vector vec = new Vector(); + for (Iterator it = cfg.iterateNodes(); it.hasNext();) { + SSACFG.BasicBlock bb = (SSACFG.BasicBlock) it.next(); + if (cfg.getPredNodeCount(bb) == 0) + vec.add(bb); + } + if (vec.size() > 1) { + /* + * Trace.println(mref+" has more than one block with no predecessors"); + * for ( int i=0 ; i callerNodes = HashSetFactory.make(); + callerNodes.addAll(cg.getNodes(thisBinaryRef)); + callerNodes.addAll(cg.getNodes(thatBinaryRef)); + Assertions._assert(callerNodes.size() == 2); + + for (Iterator nodes = callerNodes.iterator(); nodes.hasNext();) { + CGNode n = (CGNode) nodes.next(); + for (Iterator sites = n.iterateSites(); sites.hasNext();) { + CallSiteReference csRef = (CallSiteReference) sites.next(); + if (csRef.getDeclaredTarget().equals(unary2Ref)) { + numberOfCalls++; + Assertions._assert(n.getNumberOfTargets(csRef) == desiredNumberOfTargets); + } + } + } + + Assertions._assert(numberOfCalls == desiredNumberOfCalls); + } + + public void testNoPiNodes() throws ClassHierarchyException { + checkCallAssertions(doGraph(false), 2, 2); + } + + public void testPiNodes() throws ClassHierarchyException { + checkCallAssertions(doGraph(true), 1, 2); + } + +} \ No newline at end of file diff --git a/com.ibm.wala.core.tests/src/com/ibm/wala/core/tests/callGraph/ReflectionTest.java b/com.ibm.wala.core.tests/src/com/ibm/wala/core/tests/callGraph/ReflectionTest.java new file mode 100644 index 000000000..7ebe2ab44 --- /dev/null +++ b/com.ibm.wala.core.tests/src/com/ibm/wala/core/tests/callGraph/ReflectionTest.java @@ -0,0 +1,67 @@ +/******************************************************************************* + * Copyright (c) 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.core.tests.callGraph; + +import java.util.Iterator; + +import com.ibm.wala.core.tests.util.TestConstants; +import com.ibm.wala.core.tests.util.WalaTestCase; +import com.ibm.wala.ecore.java.impl.JavaPackageImpl; +import com.ibm.wala.ipa.callgraph.AnalysisOptions; +import com.ibm.wala.ipa.callgraph.AnalysisScope; +import com.ibm.wala.ipa.callgraph.Entrypoints; +import com.ibm.wala.ipa.cha.ClassHierarchy; +import com.ibm.wala.util.debug.Trace; +import com.ibm.wala.util.warnings.WalaException; +import com.ibm.wala.util.warnings.Warning; +import com.ibm.wala.util.warnings.WarningSet; + +/** + * + * Tests for Call Graph construction + * + * @author sfink + */ + +public class ReflectionTest extends WalaTestCase { + + static { + JavaPackageImpl.init(); + } + + public static void main(String[] args) { + justThisTest(ReflectionTest.class); + } + + public void testReflect1() throws WalaException { + AnalysisScope scope = CallGraphTestUtil.makeJ2SEAnalysisScope(TestConstants.WALA_TESTDATA); + WarningSet warnings = new WarningSet(); + ClassHierarchy cha = ClassHierarchy.make(scope, warnings); + Entrypoints entrypoints = com.ibm.wala.ipa.callgraph.impl.Util.makeMainEntrypoints(scope, cha, TestConstants.REFLECT1_MAIN); + AnalysisOptions options = CallGraphTestUtil.makeAnalysisOptions(scope, entrypoints); + + Trace.println("testReflect1 set up warnings:\n"); + Trace.print(warnings.toString()); + + warnings = CallGraphTest.doCallGraphs(options, cha, scope, null, useShortProfile(), false); + if (warnings.size() > 0) { + System.err.println(warnings); + } + for (Iterator it = warnings.iterator(); it.hasNext(); ) { + Warning w = (Warning)it.next(); + if (w.toString().indexOf("com/ibm/jvm") > 0) { + continue; + } + assertTrue(w.toString(), false); + } + + } +} diff --git a/com.ibm.wala.core.tests/src/com/ibm/wala/core/tests/cha/CHATest.java b/com.ibm.wala.core.tests/src/com/ibm/wala/core/tests/cha/CHATest.java new file mode 100644 index 000000000..b5e93e0d5 --- /dev/null +++ b/com.ibm.wala.core.tests/src/com/ibm/wala/core/tests/cha/CHATest.java @@ -0,0 +1,150 @@ +/******************************************************************************* + * 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.core.tests.cha; + +import java.io.File; +import java.util.Collection; +import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.Properties; + +import org.eclipse.emf.ecore.EObject; + +import com.ibm.wala.classLoader.IClass; +import com.ibm.wala.core.tests.util.TestConstants; +import com.ibm.wala.core.tests.util.WalaTestCase; +import com.ibm.wala.ecore.java.EJavaClass; +import com.ibm.wala.ecore.java.ETypeHierarchy; +import com.ibm.wala.ecore.java.impl.JavaPackageImpl; +import com.ibm.wala.emf.wrappers.EMFBridge; +import com.ibm.wala.emf.wrappers.EMFScopeWrapper; +import com.ibm.wala.emf.wrappers.ETypeHierarchyWrapper; +import com.ibm.wala.emf.wrappers.EUtil; +import com.ibm.wala.ipa.callgraph.AnalysisScope; +import com.ibm.wala.ipa.cha.ClassHierarchy; +import com.ibm.wala.ipa.cha.ClassHierarchyException; +import com.ibm.wala.properties.WalaProperties; +import com.ibm.wala.util.debug.Assertions; +import com.ibm.wala.util.debug.Trace; +import com.ibm.wala.util.warnings.WalaException; +import com.ibm.wala.util.warnings.WarningSet; + +/** + * @author sfink + */ + +public class CHATest extends WalaTestCase { + + static { + JavaPackageImpl.init(); + } + + private static final ClassLoader MY_CLASSLOADER = CHATest.class.getClassLoader(); + + public static void main(String[] args) { + justThisTest(CHATest.class); + } + + public CHATest(String arg0) { + super(arg0); + } + + /** + * regression test with class hierarchy of primordial loader + * @throws ClassHierarchyException + */ + public void testPrimordial() throws ClassHierarchyException { + System.err.println("build ..."); + // build a class hierarchy for the primordial loader + AnalysisScope scope = new EMFScopeWrapper(TestConstants.WALA_TESTDATA, "J2SEClassHierarchyExclusions.xml", MY_CLASSLOADER); + WarningSet warnings = new WarningSet(); + ClassHierarchy cha = ClassHierarchy.make(scope, warnings); + com.ibm.wala.emf.wrappers.ETypeHierarchyWrapper t1 = EMFBridge.makeTypeHierarchy(cha); + System.err.println("save ..."); + // save it to disk + ETypeHierarchy et = (ETypeHierarchy) t1.toEMF(); + Properties p = null;; + try { + p = WalaProperties.loadProperties(); + } catch (WalaException e) { + e.printStackTrace(); + Assertions.UNREACHABLE(); + } + String outputDir = p.getProperty(WalaProperties.OUTPUT_DIR); + String fileName = outputDir + File.separator + "primordialTH.xml"; + Collection persist = new LinkedList(); + persist.add(et); + persist.add(et.getClasses().getNodes()); + persist.add(et.getInterfaces().getNodes()); + try { + EUtil.saveToFile(persist, fileName); + } catch (WalaException e1) { + e1.printStackTrace(); + Assertions.UNREACHABLE("failed to save to file " + fileName + "\n. outputDir was " + outputDir); + } + + System.err.println("read ..."); + // load it back into memory + ETypeHierarchyWrapper et2 = ETypeHierarchyWrapper.loadFromFile(fileName); + System.err.println("check ..."); + // check that they are isomorphic + // TODO: add general utilities for isomorphism + com.ibm.wala.ipa.callgraph.impl.Util.checkGraphSubset(t1.getClasses(), et2.getClasses()); + com.ibm.wala.ipa.callgraph.impl.Util.checkGraphSubset(et2.getClasses(), t1.getClasses()); + com.ibm.wala.ipa.callgraph.impl.Util.checkGraphSubset(t1.getInterfaces(), et2.getInterfaces()); + com.ibm.wala.ipa.callgraph.impl.Util.checkGraphSubset(et2.getInterfaces(), t1.getInterfaces()); + checkInterfaces(cha, et2); + } + + /** + * check that the set of interfaces for each class is consistent between cha + * and T. + * + * @param cha + * @param T + */ + private void checkInterfaces(ClassHierarchy cha, ETypeHierarchyWrapper T) { + try { + for (Iterator it = cha.iterateAllClasses(); it.hasNext();) { + IClass klass = (IClass) it.next(); + if (!klass.isInterface()) { + EJavaClass eKlass = EMFBridge.makeJavaClass(klass.getReference()); + HashSet impls = new HashSet(5); + for (Iterator it2 = klass.getDirectInterfaces().iterator(); it2.hasNext();) { + IClass iface = (IClass) it2.next(); + impls.add(EMFBridge.makeJavaClass(iface.getReference())); + } + Collection c = T.getImplements(eKlass); + checkSetsEqual(impls, c); + } + } + } catch (ClassHierarchyException e) { + e.printStackTrace(); + Assertions.UNREACHABLE(); + } + } + + private void checkSetsEqual(Collection c1, Collection c2) { + if (!c1.containsAll(c2)) { + c2.removeAll(c1); + Trace.printCollection("DIFF: c2 contains but not c1 ", c2); + assertTrue("c1 not superset of c2, see trace file for details", false); + return; + } + if (!c2.containsAll(c1)) { + c1.removeAll(c2); + Trace.printCollection("DIFF: c1 contains but not c2 ", c1); + assertTrue("c2 not superset of c1, see trace file for details", false); + return; + } + } +} diff --git a/com.ibm.wala.core.tests/src/com/ibm/wala/core/tests/cha/LibraryVersionTest.java b/com.ibm.wala.core.tests/src/com/ibm/wala/core/tests/cha/LibraryVersionTest.java new file mode 100644 index 000000000..c007d3038 --- /dev/null +++ b/com.ibm.wala.core.tests/src/com/ibm/wala/core/tests/cha/LibraryVersionTest.java @@ -0,0 +1,37 @@ +/******************************************************************************* + * 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.core.tests.cha; + +import junit.framework.Assert; + +import com.ibm.wala.core.tests.ir.DeterministicIRTest; +import com.ibm.wala.core.tests.util.TestConstants; +import com.ibm.wala.core.tests.util.WalaTestCase; +import com.ibm.wala.emf.wrappers.EMFScopeWrapper; +import com.ibm.wala.ipa.callgraph.AnalysisScope; + +/** + * Test code that attempts to find the library version from + * the analysis scope. + * + * @author JulianDolby (dolby@us.ibm.com) + */ +public class LibraryVersionTest extends WalaTestCase { + + private static final ClassLoader MY_CLASSLOADER = DeterministicIRTest.class.getClassLoader(); + + public void testLibraryVersion() { + AnalysisScope scope = new EMFScopeWrapper(TestConstants.WALA_TESTDATA, "J2SEClassHierarchyExclusions.xml", MY_CLASSLOADER); + System.err.println("java library version is " + scope.getJavaLibraryVersion()); + Assert.assertTrue(scope.isJava15Libraries()||scope.isJava14Libraries()); + } + +} diff --git a/com.ibm.wala.core.tests/src/com/ibm/wala/core/tests/cha/SourceMapTest.java b/com.ibm.wala.core.tests/src/com/ibm/wala/core/tests/cha/SourceMapTest.java new file mode 100644 index 000000000..4ca6d9d27 --- /dev/null +++ b/com.ibm.wala.core.tests/src/com/ibm/wala/core/tests/cha/SourceMapTest.java @@ -0,0 +1,60 @@ +/******************************************************************************* + * 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.core.tests.cha; + +import com.ibm.wala.classLoader.IClass; +import com.ibm.wala.core.tests.util.TestConstants; +import com.ibm.wala.core.tests.util.WalaTestCase; +import com.ibm.wala.emf.wrappers.EMFScopeWrapper; +import com.ibm.wala.ipa.callgraph.AnalysisScope; +import com.ibm.wala.ipa.cha.ClassHierarchy; +import com.ibm.wala.ipa.cha.ClassHierarchyException; +import com.ibm.wala.types.TypeReference; +import com.ibm.wala.util.warnings.WarningSet; + +/** + * A test of support for source file mapping + * + * @author sfink + */ +public class SourceMapTest extends WalaTestCase { + private static final ClassLoader MY_CLASSLOADER = SourceMapTest.class.getClassLoader(); + + private final static String CLASS_IN_PRIMORDIAL_JAR = "Lcom/ibm/wala/model/SyntheticFactory"; + + public void testHello() throws ClassHierarchyException { + AnalysisScope scope = null; + scope = new EMFScopeWrapper(TestConstants.HELLO, null, MY_CLASSLOADER); + // TODO: it's annoying to have to build a class hierarchy here. + // see feature 38676 + ClassHierarchy cha = ClassHierarchy.make(scope, new WarningSet()); + TypeReference t = TypeReference.findOrCreate(scope.getApplicationLoader(), TestConstants.HELLO_MAIN); + IClass klass = cha.lookupClass(t); + assertTrue("failed to load " + t, klass != null); + String sourceFile = klass.getSourceFileName(); + System.err.println("Source file: " + sourceFile); + assertTrue(sourceFile != null); + } + + public void testFromJar() throws ClassHierarchyException { + AnalysisScope scope = null; + scope = new EMFScopeWrapper(TestConstants.HELLO, null, MY_CLASSLOADER); + // TODO: it's annoying to have to build a class hierarchy here. + // open a feature to fix this + ClassHierarchy cha = ClassHierarchy.make(scope, new WarningSet()); + TypeReference t = TypeReference.findOrCreate(scope.getPrimordialLoader(), CLASS_IN_PRIMORDIAL_JAR); + IClass klass = cha.lookupClass(t); + assertTrue(klass != null); + String sourceFile = klass.getSourceFileName(); + assertTrue(sourceFile != null); + System.err.println("Source file: " + sourceFile); + } +} \ No newline at end of file diff --git a/com.ibm.wala.core.tests/src/com/ibm/wala/core/tests/ir/CFGTest.java b/com.ibm.wala.core.tests/src/com/ibm/wala/core/tests/ir/CFGTest.java new file mode 100644 index 000000000..98cdb8515 --- /dev/null +++ b/com.ibm.wala.core.tests/src/com/ibm/wala/core/tests/ir/CFGTest.java @@ -0,0 +1,97 @@ +/******************************************************************************* + * 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.core.tests.ir; + +import com.ibm.wala.cfg.ControlFlowGraph; +import com.ibm.wala.cfg.TwoExitCFG; +import com.ibm.wala.classLoader.IMethod; +import com.ibm.wala.core.tests.util.WalaTestCase; +import com.ibm.wala.ecore.java.scope.EJavaAnalysisScope; +import com.ibm.wala.emf.wrappers.EMFScopeWrapper; +import com.ibm.wala.emf.wrappers.JavaScopeUtil; +import com.ibm.wala.ipa.callgraph.AnalysisOptions; +import com.ibm.wala.ipa.callgraph.impl.Everywhere; +import com.ibm.wala.ipa.cha.ClassHierarchy; +import com.ibm.wala.ssa.IR; +import com.ibm.wala.types.MethodReference; +import com.ibm.wala.util.StringStuff; +import com.ibm.wala.util.debug.Assertions; +import com.ibm.wala.util.debug.Trace; +import com.ibm.wala.util.graph.GraphIntegrity; +import com.ibm.wala.util.graph.GraphIntegrity.UnsoundGraphException; +import com.ibm.wala.util.warnings.WarningSet; + +/** + * Test integrity of CFGs + */ +public class CFGTest extends WalaTestCase { + + public static void main(String[] args) { + justThisTest(CFGTest.class); + } + + /** + * Build an IR, then check integrity on two flavors of CFG + */ + private void doMethod(String methodSig) { + try { + EJavaAnalysisScope escope = JavaScopeUtil.makePrimordialScope(); + + // generate a DOMO-consumable wrapper around the incoming scope object + EMFScopeWrapper scope = EMFScopeWrapper.generateScope(escope); + + // invoke DOMO to build a DOMO class hierarchy object + WarningSet warnings = new WarningSet(); + ClassHierarchy cha = ClassHierarchy.make(scope, warnings); + + MethodReference mr = StringStuff.makeMethodReference(methodSig); + + IMethod m = cha.resolveMethod(mr); + if (m == null) { + Assertions.UNREACHABLE("could not resolve " + mr); + } + AnalysisOptions options = new AnalysisOptions(); + options.getSSAOptions().setUsePiNodes(true); + IR ir = options.getSSACache().findOrCreateIR(m, Everywhere.EVERYWHERE, cha, options.getSSAOptions(), new WarningSet()); + + ControlFlowGraph cfg = ir.getControlFlowGraph(); + try { + GraphIntegrity.check(cfg); + } catch (UnsoundGraphException e) { + e.printStackTrace(); + Trace.println(ir); + assertTrue(" failed cfg integrity check for " + methodSig, false); + } + + cfg = new TwoExitCFG(cfg); + try { + GraphIntegrity.check(cfg); + } catch (UnsoundGraphException e) { + e.printStackTrace(); + Trace.println(ir); + Trace.println(cfg); + assertTrue(" failed 2-exit cfg integrity check for " + methodSig, false); + } + } catch (Exception e) { + e.printStackTrace(); + Assertions.UNREACHABLE(); + } + } + + /** + * this method does not exist in 1.5 libraries public void testFDBigInt() { + * doMethod("java.lang.FDBigInt.class$(Ljava/lang/String;)Ljava/lang/Class;"); } + */ + + public void testResolveProxyClass() { + doMethod("java.io.ObjectInputStream.resolveProxyClass([Ljava/lang/String;)Ljava/lang/Class;"); + } +} diff --git a/com.ibm.wala.core.tests/src/com/ibm/wala/core/tests/ir/CornerCasesTest.java b/com.ibm.wala.core.tests/src/com/ibm/wala/core/tests/ir/CornerCasesTest.java new file mode 100644 index 000000000..ade83e2ae --- /dev/null +++ b/com.ibm.wala.core.tests/src/com/ibm/wala/core/tests/ir/CornerCasesTest.java @@ -0,0 +1,83 @@ +/******************************************************************************* + * 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.core.tests.ir; + +import com.ibm.wala.analysis.typeInference.TypeInference; +import com.ibm.wala.classLoader.IClass; +import com.ibm.wala.classLoader.IMethod; +import com.ibm.wala.classLoader.ShrikeCTMethodWrapper; +import com.ibm.wala.core.tests.util.TestConstants; +import com.ibm.wala.core.tests.util.WalaTestCase; +import com.ibm.wala.emf.wrappers.EMFScopeWrapper; +import com.ibm.wala.ipa.callgraph.AnalysisOptions; +import com.ibm.wala.ipa.callgraph.AnalysisScope; +import com.ibm.wala.ipa.callgraph.impl.Everywhere; +import com.ibm.wala.ipa.cha.ClassHierarchy; +import com.ibm.wala.ipa.cha.ClassHierarchyException; +import com.ibm.wala.ssa.IR; +import com.ibm.wala.types.Descriptor; +import com.ibm.wala.types.Selector; +import com.ibm.wala.types.TypeReference; +import com.ibm.wala.util.Atom; +import com.ibm.wala.util.debug.Trace; +import com.ibm.wala.util.warnings.WarningSet; + +/** + * tests for weird corner cases, such as when the input program doesn't verify + * + * @author sfink + */ +public class CornerCasesTest extends WalaTestCase { + + private static final ClassLoader MY_CLASSLOADER = CornerCasesTest.class.getClassLoader(); + + /** + * test that getMethod() works even if a declared ancester interface doesn't + * exist + * @throws ClassHierarchyException + */ + public void testBug38484() throws ClassHierarchyException { + AnalysisScope scope = null; + scope = new EMFScopeWrapper(TestConstants.WALA_TESTDATA, "J2SEClassHierarchyExclusions.xml", MY_CLASSLOADER); + WarningSet warnings = new WarningSet(); + ClassHierarchy cha = ClassHierarchy.make(scope, warnings); + TypeReference t = TypeReference.findOrCreateClass(scope.getApplicationLoader(), "cornerCases", "YuckyInterface"); + IClass klass = cha.lookupClass(t); + assertTrue(klass != null); + IMethod m = klass.getMethod(new Selector(Atom.findOrCreateAsciiAtom("x"), Descriptor.findOrCreateUTF8("()V"))); + assertTrue(m == null); + Trace.print(warnings.toString()); + } + + /** + * test that type inference works in the presence of a getfield where the + * field's declared type cannot be loaded + * @throws ClassHierarchyException + */ + public void testBug38540() throws ClassHierarchyException { + AnalysisScope scope = null; + scope = new EMFScopeWrapper(TestConstants.WALA_TESTDATA, "J2SEClassHierarchyExclusions.xml", MY_CLASSLOADER); + AnalysisOptions options = new AnalysisOptions(); + WarningSet warnings = new WarningSet(); + ClassHierarchy cha = ClassHierarchy.make(scope, warnings); + TypeReference t = TypeReference.findOrCreateClass(scope.getApplicationLoader(), "cornerCases", "Main"); + IClass klass = cha.lookupClass(t); + assertTrue(klass != null); + ShrikeCTMethodWrapper m = (ShrikeCTMethodWrapper) klass.getMethod(new Selector(Atom.findOrCreateAsciiAtom("foo"), Descriptor + .findOrCreateUTF8("()Ljava/lang/Object;"))); + assertTrue(m != null); + IR ir = options.getIRFactory().makeIR(m, Everywhere.EVERYWHERE, cha, options.getSSAOptions(), warnings); + new TypeInference(ir, cha); + + Trace.print(warnings.toString()); + } + +} diff --git a/com.ibm.wala.core.tests/src/com/ibm/wala/core/tests/ir/DeterministicIRTest.java b/com.ibm.wala.core.tests/src/com/ibm/wala/core/tests/ir/DeterministicIRTest.java new file mode 100644 index 000000000..9adaf30f5 --- /dev/null +++ b/com.ibm.wala.core.tests/src/com/ibm/wala/core/tests/ir/DeterministicIRTest.java @@ -0,0 +1,216 @@ +/******************************************************************************* + * 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.core.tests.ir; + +import java.util.Iterator; + +import com.ibm.wala.classLoader.ClassLoaderFactory; +import com.ibm.wala.classLoader.ClassLoaderFactoryImpl; +import com.ibm.wala.classLoader.IMethod; +import com.ibm.wala.core.tests.util.TestConstants; +import com.ibm.wala.core.tests.util.WalaTestCase; +import com.ibm.wala.emf.wrappers.EMFScopeWrapper; +import com.ibm.wala.ipa.callgraph.AnalysisOptions; +import com.ibm.wala.ipa.callgraph.AnalysisScope; +import com.ibm.wala.ipa.callgraph.impl.Everywhere; +import com.ibm.wala.ipa.cha.ClassHierarchy; +import com.ibm.wala.ipa.cha.ClassHierarchyException; +import com.ibm.wala.ssa.IR; +import com.ibm.wala.ssa.SSAInstruction; +import com.ibm.wala.types.MethodReference; +import com.ibm.wala.util.Atom; +import com.ibm.wala.util.ImmutableByteArray; +import com.ibm.wala.util.UTF8Convert; +import com.ibm.wala.util.graph.GraphIntegrity; +import com.ibm.wala.util.graph.GraphIntegrity.UnsoundGraphException; +import com.ibm.wala.util.warnings.WarningSet; + +/** + * Test that the SSA-numbering of variables in the IR is deterministic. + * + * Introduced 05-AUG-03; the default implementation of hashCode was being + * invoked. Object.hashCode is a source of random numbers and has no place in a + * deterministic program. + */ +public class DeterministicIRTest extends WalaTestCase { + + private static final ClassLoader MY_CLASSLOADER = DeterministicIRTest.class.getClassLoader(); + + private WarningSet warnings; + private AnalysisScope scope; + private ClassHierarchy cha; + private AnalysisOptions options; + + public static void main(String[] args) { + justThisTest(DeterministicIRTest.class); + } + + /* + * (non-Javadoc) + * + * @see junit.framework.TestCase#setUp() + */ + protected void setUp() throws Exception { + + warnings = new WarningSet(); + scope = new EMFScopeWrapper(TestConstants.WALA_TESTDATA, "J2SEClassHierarchyExclusions.xml", MY_CLASSLOADER); + + options = new AnalysisOptions(scope, null); + ClassLoaderFactory factory = new ClassLoaderFactoryImpl(scope.getExclusions(), warnings); + + warnings = new WarningSet(); + + try { + cha = ClassHierarchy.make(scope, factory, warnings); + } catch (ClassHierarchyException e) { + throw new Exception(); + } + } + + /* + * (non-Javadoc) + * + * @see junit.framework.TestCase#tearDown() + */ + protected void tearDown() throws Exception { + warnings = null; + scope = null; + cha = null; + super.tearDown(); + } + + /** + * @param method + */ + private IR doMethod(MethodReference method) { + assertNotNull("method not found", method); + IMethod imethod = cha.resolveMethod(method); + assertNotNull("imethod not found", imethod); + IR ir1 = options.getIRFactory().makeIR(imethod, Everywhere.EVERYWHERE, cha, options.getSSAOptions(), warnings); + options.getSSACache().wipe(); + + checkNotAllNull(ir1.getInstructions()); + checkNoneNull(ir1.iterateAllInstructions()); + try { + GraphIntegrity.check(ir1.getControlFlowGraph()); + } catch (UnsoundGraphException e) { + System.err.println(ir1); + e.printStackTrace(); + assertTrue("unsound CFG for ir1", false); + } + + IR ir2 = options.getIRFactory().makeIR(imethod, Everywhere.EVERYWHERE, cha, options.getSSAOptions(), warnings); + options.getSSACache().wipe(); + + try { + GraphIntegrity.check(ir2.getControlFlowGraph()); + } catch (UnsoundGraphException e1) { + System.err.println(ir2); + e1.printStackTrace(); + assertTrue("unsound CFG for ir2", false); + } + + assertEquals(ir1.toString(), ir2.toString()); + return ir1; + } + + // The Tests /////////////////////////////////////////////////////// + + /** + * @param iterator + */ + private void checkNoneNull(Iterator iterator) { + while (iterator.hasNext()) { + assertTrue(iterator.next() != null); + } + + } + + /** + * @param instructions + */ + private static void checkNotAllNull(SSAInstruction[] instructions) { + for (int i = 0; i < instructions.length; i++) { + if (instructions[i] != null) { + return; + } + } + assertTrue("no instructions generated", false); + } + + public void testIR1() { + // 'remove' is a nice short method + doMethod(scope.findMethod(AnalysisScope.APPLICATION, "Ljava/util/HashMap", Atom.findOrCreateUnicodeAtom("remove"), + new ImmutableByteArray(UTF8Convert.toUTF8("(Ljava/lang/Object;)Ljava/lang/Object;")))); + } + + public void testIR2() { + // 'equals' is a nice medium-sized method + doMethod(scope.findMethod(AnalysisScope.APPLICATION, "Ljava/lang/String", Atom.findOrCreateUnicodeAtom("equals"), + new ImmutableByteArray(UTF8Convert.toUTF8("(Ljava/lang/Object;)Z")))); + } + + public void testIR3() { + // 'resolveProxyClass' is a nice long method (at least in Sun libs) + doMethod(scope.findMethod(AnalysisScope.APPLICATION, "Ljava/io/ObjectInputStream", Atom + .findOrCreateUnicodeAtom("resolveProxyClass"), new ImmutableByteArray(UTF8Convert + .toUTF8("([Ljava/lang/String;)Ljava/lang/Class;")))); + } + + public void testLocalNamesWithoutPiNodes() { + boolean save = options.getSSAOptions().getUsePiNodes(); + options.getSSAOptions().setUsePiNodes( false ); + IR ir = doMethod(scope.findMethod(AnalysisScope.APPLICATION, "LcornerCases/Locals", Atom.findOrCreateUnicodeAtom("foo"), + new ImmutableByteArray(UTF8Convert.toUTF8("([Ljava/lang/String;)V")))); + options.getSSAOptions().setUsePiNodes( save ); + + + // v1 should be the parameter "a" at pc 0 + String[] names = ir.getLocalNames(0,1); + assertTrue("failed local name resolution for v1@0" , names != null); + assertTrue("incorrect number of local names for v1@0: " + names.length , names.length == 1); + assertTrue("incorrect local name resolution for v1@0: " + names[0], names[0].equals("a")); + + // v2 is a compiler-induced temporary + assertTrue("didn't expect name for v2 at pc 2" , ir.getLocalNames(2,2) == null); + + // at pc 5, v1 should represent the locals "a" and "b" + names = ir.getLocalNames(5,1); + assertTrue("failed local name resolution for v1@5" , names != null); + assertTrue("incorrect number of local names for v1@5: " + names.length , names.length == 2); + assertTrue("incorrect local name resolution #0 for v1@5: " + names[0], names[0].equals("a")); + assertTrue("incorrect local name resolution #1 for v1@5: " + names[1], names[1].equals("b")); + } + + public void testLocalNamesWithPiNodes() { + boolean save = options.getSSAOptions().getUsePiNodes(); + options.getSSAOptions().setUsePiNodes( true ); + IR ir = doMethod(scope.findMethod(AnalysisScope.APPLICATION, "LcornerCases/Locals", Atom.findOrCreateUnicodeAtom("foo"), + new ImmutableByteArray(UTF8Convert.toUTF8("([Ljava/lang/String;)V")))); + options.getSSAOptions().setUsePiNodes( save ); + + // v1 should be the parameter "a" at pc 0 + String[] names = ir.getLocalNames(0,1); + assertTrue("failed local name resolution for v1@0" , names != null); + assertTrue("incorrect number of local names for v1@0: " + names.length , names.length == 1); + assertTrue("incorrect local name resolution for v1@0: " + names[0], names[0].equals("a")); + + // v2 is a compiler-induced temporary + assertTrue("didn't expect name for v2 at pc 2" , ir.getLocalNames(2,2) == null); + + // at pc 5, v1 should represent the locals "a" and "b" + names = ir.getLocalNames(5,1); + assertTrue("failed local name resolution for v1@5" , names != null); + assertTrue("incorrect number of local names for v1@5: " + names.length , names.length == 2); + assertTrue("incorrect local name resolution #0 for v1@5: " + names[0], names[0].equals("a")); + assertTrue("incorrect local name resolution #1 for v1@5: " + names[1], names[1].equals("b")); + } +} diff --git a/com.ibm.wala.core.tests/src/com/ibm/wala/core/tests/ptrs/MultiDimArrayTest.java b/com.ibm.wala.core.tests/src/com/ibm/wala/core/tests/ptrs/MultiDimArrayTest.java new file mode 100644 index 000000000..cb94b715e --- /dev/null +++ b/com.ibm.wala.core.tests/src/com/ibm/wala/core/tests/ptrs/MultiDimArrayTest.java @@ -0,0 +1,92 @@ +/******************************************************************************* + * Copyright (c) 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.core.tests.ptrs; + +import java.util.Iterator; + +import com.ibm.wala.core.tests.callGraph.CallGraphTestUtil; +import com.ibm.wala.core.tests.util.TestConstants; +import com.ibm.wala.core.tests.util.WalaTestCase; +import com.ibm.wala.ipa.callgraph.AnalysisOptions; +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.CallGraphBuilder; +import com.ibm.wala.ipa.callgraph.Entrypoints; +import com.ibm.wala.ipa.callgraph.impl.Util; +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.ipa.cha.ClassHierarchy; +import com.ibm.wala.ipa.cha.ClassHierarchyException; +import com.ibm.wala.util.debug.Assertions; +import com.ibm.wala.util.intset.OrdinalSet; +import com.ibm.wala.util.warnings.WarningSet; + +/** + * + * Test for pointer analysis of multidimensional arrays + * + * @author sfink + */ + +public class MultiDimArrayTest extends WalaTestCase { + + + public static void main(String[] args) { + justThisTest(MultiDimArrayTest.class); + } + + /** + * Constructor for SpecJTest. + * + * @param arg0 + */ + public MultiDimArrayTest(String arg0) { + super(arg0); + } + + + public void testMultiDim() throws ClassHierarchyException { + + AnalysisScope scope = CallGraphTestUtil.makeJ2SEAnalysisScope(TestConstants.WALA_TESTDATA); + WarningSet warnings = new WarningSet(); + ClassHierarchy cha = ClassHierarchy.make(scope, warnings); + Entrypoints entrypoints = com.ibm.wala.ipa.callgraph.impl.Util + .makeMainEntrypoints(scope, cha, TestConstants.MULTI_DIM_MAIN); + AnalysisOptions options = CallGraphTestUtil.makeAnalysisOptions(scope, entrypoints); + + CallGraphBuilder builder = Util.makeVanillaZeroOneCFABuilder(options, cha, scope, warnings); + CallGraph cg = builder.makeCallGraph(options); + PointerAnalysis pa = builder.getPointerAnalysis(); + System.err.println(pa); + + CGNode node = findDoNothingNode(cg); + PointerKey pk = pa.getHeapModel().getPointerKeyForLocal(node, 1); + OrdinalSet ptsTo = pa.getPointsToSet(pk); + assertEquals(1, ptsTo.size()); + } + + private final static CGNode findDoNothingNode(CallGraph cg) { + for (Iterator it = cg.iterateNodes(); it.hasNext(); ) { + CGNode n = it.next(); + if (n.getMethod().getName().toString().equals("doNothing")) { + return n; + } + } + Assertions.UNREACHABLE("Unexpected: failed to find doNothing node"); + return null; + } + + + + +} diff --git a/com.ibm.wala.core.tests/src/com/ibm/wala/core/tests/slicer/SlicerTest.java b/com.ibm.wala.core.tests/src/com/ibm/wala/core/tests/slicer/SlicerTest.java new file mode 100644 index 000000000..9d5db355a --- /dev/null +++ b/com.ibm.wala.core.tests/src/com/ibm/wala/core/tests/slicer/SlicerTest.java @@ -0,0 +1,542 @@ +/******************************************************************************* + * Copyright (c) 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.core.tests.slicer; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.PrintWriter; +import java.util.Collection; +import java.util.Iterator; + +import junit.framework.TestCase; + +import com.ibm.wala.core.tests.callGraph.CallGraphTestUtil; +import com.ibm.wala.core.tests.util.TestConstants; +import com.ibm.wala.examples.drivers.GVSlice; +import com.ibm.wala.ipa.callgraph.AnalysisOptions; +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.CallGraphBuilder; +import com.ibm.wala.ipa.callgraph.Entrypoints; +import com.ibm.wala.ipa.callgraph.impl.Util; +import com.ibm.wala.ipa.cha.ClassHierarchy; +import com.ibm.wala.ipa.cha.ClassHierarchyException; +import com.ibm.wala.ipa.slicer.NormalStatement; +import com.ibm.wala.ipa.slicer.Slicer; +import com.ibm.wala.ipa.slicer.Statement; +import com.ibm.wala.ipa.slicer.Slicer.ControlDependenceOptions; +import com.ibm.wala.ipa.slicer.Slicer.DataDependenceOptions; +import com.ibm.wala.ssa.IR; +import com.ibm.wala.ssa.SSAArrayLoadInstruction; +import com.ibm.wala.ssa.SSAConditionalBranchInstruction; +import com.ibm.wala.ssa.SSAGetInstruction; +import com.ibm.wala.ssa.SSAInstruction; +import com.ibm.wala.ssa.SSAInvokeInstruction; +import com.ibm.wala.ssa.SSANewInstruction; +import com.ibm.wala.ssa.SSAPutInstruction; +import com.ibm.wala.types.Descriptor; +import com.ibm.wala.util.Atom; +import com.ibm.wala.util.debug.Assertions; +import com.ibm.wala.util.intset.IntSet; +import com.ibm.wala.util.warnings.WarningSet; + +public class SlicerTest extends TestCase { + + public void testSlice1() throws ClassHierarchyException { + AnalysisScope scope = CallGraphTestUtil.makeJ2SEAnalysisScope(TestConstants.WALA_TESTDATA); + WarningSet warnings = new WarningSet(); + ClassHierarchy cha = ClassHierarchy.make(scope, warnings); + Entrypoints entrypoints = com.ibm.wala.ipa.callgraph.impl.Util.makeMainEntrypoints(scope, cha, TestConstants.SLICE1_MAIN); + AnalysisOptions options = CallGraphTestUtil.makeAnalysisOptions(scope, entrypoints); + + CallGraphBuilder builder = Util.makeZeroOneCFABuilder(options, cha, scope, warnings); + CallGraph cg = builder.makeCallGraph(options); + + CGNode main = findMainMethod(cg); + + Statement s = findCallTo(main, "print"); + System.err.println("Statement: " + s); + // compute a data slice + Collection slice = Slicer.computeBackwardSlice(s, cg, builder.getPointerAnalysis(), DataDependenceOptions.FULL, + ControlDependenceOptions.NONE); + dumpSlice(slice); + assertEquals(18, slice.size()); + } + + public void testSlice2() throws ClassHierarchyException { + AnalysisScope scope = CallGraphTestUtil.makeJ2SEAnalysisScope(TestConstants.WALA_TESTDATA); + WarningSet warnings = new WarningSet(); + ClassHierarchy cha = ClassHierarchy.make(scope, warnings); + Entrypoints entrypoints = com.ibm.wala.ipa.callgraph.impl.Util.makeMainEntrypoints(scope, cha, TestConstants.SLICE2_MAIN); + AnalysisOptions options = CallGraphTestUtil.makeAnalysisOptions(scope, entrypoints); + + CallGraphBuilder builder = Util.makeZeroOneCFABuilder(options, cha, scope, warnings); + CallGraph cg = builder.makeCallGraph(options); + + CGNode main = findMethod(cg, "baz"); + + Statement s = findCallTo(main, "print"); + System.err.println("Statement: " + s); + // compute a data slice + Collection slice = Slicer.computeBackwardSlice(s, cg, builder.getPointerAnalysis(), DataDependenceOptions.FULL, + ControlDependenceOptions.NONE); + dumpSlice(slice); + assertEquals(22, slice.size()); + } + + public void testSlice3() throws ClassHierarchyException { + AnalysisScope scope = CallGraphTestUtil.makeJ2SEAnalysisScope(TestConstants.WALA_TESTDATA); + WarningSet warnings = new WarningSet(); + ClassHierarchy cha = ClassHierarchy.make(scope, warnings); + Entrypoints entrypoints = com.ibm.wala.ipa.callgraph.impl.Util.makeMainEntrypoints(scope, cha, TestConstants.SLICE3_MAIN); + AnalysisOptions options = CallGraphTestUtil.makeAnalysisOptions(scope, entrypoints); + + CallGraphBuilder builder = Util.makeZeroOneCFABuilder(options, cha, scope, warnings); + CallGraph cg = builder.makeCallGraph(options); + + CGNode main = findMethod(cg, "main"); + + Statement s = findCallTo(main, "doNothing"); + System.err.println("Statement: " + s); + // compute a data slice + Collection slice = Slicer.computeBackwardSlice(s, cg, builder.getPointerAnalysis(), DataDependenceOptions.FULL, + ControlDependenceOptions.NONE); + dumpSlice(slice); + assertEquals(1, countAllocations(slice)); + } + + public void testSlice4() throws ClassHierarchyException { + AnalysisScope scope = CallGraphTestUtil.makeJ2SEAnalysisScope(TestConstants.WALA_TESTDATA); + WarningSet warnings = new WarningSet(); + ClassHierarchy cha = ClassHierarchy.make(scope, warnings); + Entrypoints entrypoints = com.ibm.wala.ipa.callgraph.impl.Util.makeMainEntrypoints(scope, cha, TestConstants.SLICE4_MAIN); + AnalysisOptions options = CallGraphTestUtil.makeAnalysisOptions(scope, entrypoints); + + CallGraphBuilder builder = Util.makeZeroOneCFABuilder(options, cha, scope, warnings); + CallGraph cg = builder.makeCallGraph(options); + + CGNode main = findMainMethod(cg); + Statement s = findCallTo(main, "foo"); + s = GVSlice.getReturnStatementForCall(s); + System.err.println("Statement: " + s); + // compute a data slice + Collection slice = Slicer.computeForwardSlice(s, cg, builder.getPointerAnalysis(), DataDependenceOptions.FULL, + ControlDependenceOptions.NONE); + dumpSlice(slice); + assertEquals(4, slice.size()); + } + + public void testSlice5() throws ClassHierarchyException { + AnalysisScope scope = CallGraphTestUtil.makeJ2SEAnalysisScope(TestConstants.WALA_TESTDATA); + WarningSet warnings = new WarningSet(); + ClassHierarchy cha = ClassHierarchy.make(scope, warnings); + Entrypoints entrypoints = com.ibm.wala.ipa.callgraph.impl.Util.makeMainEntrypoints(scope, cha, TestConstants.SLICE5_MAIN); + AnalysisOptions options = CallGraphTestUtil.makeAnalysisOptions(scope, entrypoints); + + CallGraphBuilder builder = Util.makeZeroOneCFABuilder(options, cha, scope, warnings); + CallGraph cg = builder.makeCallGraph(options); + + CGNode n = findMethod(cg, "baz"); + Statement s = findCallTo(n, "foo"); + s = GVSlice.getReturnStatementForCall(s); + System.err.println("Statement: " + s); + // compute a data slice + Collection slice = Slicer.computeForwardSlice(s, cg, builder.getPointerAnalysis(), DataDependenceOptions.FULL, + ControlDependenceOptions.NONE); + dumpSlice(slice); + assertEquals(7, slice.size()); + } + + public void testTestCD1() throws ClassHierarchyException { + AnalysisScope scope = CallGraphTestUtil.makeJ2SEAnalysisScope(TestConstants.WALA_TESTDATA); + WarningSet warnings = new WarningSet(); + ClassHierarchy cha = ClassHierarchy.make(scope, warnings); + Entrypoints entrypoints = com.ibm.wala.ipa.callgraph.impl.Util.makeMainEntrypoints(scope, cha, TestConstants.SLICE_TESTCD1); + AnalysisOptions options = CallGraphTestUtil.makeAnalysisOptions(scope, entrypoints); + + CallGraphBuilder builder = Util.makeZeroOneCFABuilder(options, cha, scope, warnings); + CallGraph cg = builder.makeCallGraph(options); + + CGNode main = findMainMethod(cg); + + Statement s = findCallToDoNothing(main); + System.err.println("Statement: " + s); + // compute a data slice + Collection slice = Slicer.computeBackwardSlice(s, cg, builder.getPointerAnalysis(), DataDependenceOptions.NONE, + ControlDependenceOptions.FULL); + dumpSlice(slice); + assertEquals(2, countConditionals(slice)); + } + + public void testTestCD2() throws ClassHierarchyException { + AnalysisScope scope = CallGraphTestUtil.makeJ2SEAnalysisScope(TestConstants.WALA_TESTDATA); + WarningSet warnings = new WarningSet(); + ClassHierarchy cha = ClassHierarchy.make(scope, warnings); + Entrypoints entrypoints = com.ibm.wala.ipa.callgraph.impl.Util.makeMainEntrypoints(scope, cha, TestConstants.SLICE_TESTCD2); + AnalysisOptions options = CallGraphTestUtil.makeAnalysisOptions(scope, entrypoints); + + CallGraphBuilder builder = Util.makeZeroOneCFABuilder(options, cha, scope, warnings); + CallGraph cg = builder.makeCallGraph(options); + + CGNode main = findMainMethod(cg); + + Statement s = findCallToDoNothing(main); + System.err.println("Statement: " + s); + // compute a data slice + Collection slice = Slicer.computeBackwardSlice(s, cg, builder.getPointerAnalysis(), DataDependenceOptions.NONE, + ControlDependenceOptions.FULL); + dumpSlice(slice); + assertEquals(1, countConditionals(slice)); + } + + public void testTestCD3() throws ClassHierarchyException { + AnalysisScope scope = CallGraphTestUtil.makeJ2SEAnalysisScope(TestConstants.WALA_TESTDATA); + WarningSet warnings = new WarningSet(); + ClassHierarchy cha = ClassHierarchy.make(scope, warnings); + Entrypoints entrypoints = com.ibm.wala.ipa.callgraph.impl.Util.makeMainEntrypoints(scope, cha, TestConstants.SLICE_TESTCD3); + AnalysisOptions options = CallGraphTestUtil.makeAnalysisOptions(scope, entrypoints); + + CallGraphBuilder builder = Util.makeZeroOneCFABuilder(options, cha, scope, warnings); + CallGraph cg = builder.makeCallGraph(options); + + CGNode main = findMainMethod(cg); + + Statement s = findCallToDoNothing(main); + System.err.println("Statement: " + s); + // compute a data slice + Collection slice = Slicer.computeBackwardSlice(s, cg, builder.getPointerAnalysis(), DataDependenceOptions.NONE, + ControlDependenceOptions.FULL); + dumpSlice(slice); + assertEquals(0, countConditionals(slice)); + } + + public void testTestId() throws ClassHierarchyException { + AnalysisScope scope = CallGraphTestUtil.makeJ2SEAnalysisScope(TestConstants.WALA_TESTDATA); + WarningSet warnings = new WarningSet(); + ClassHierarchy cha = ClassHierarchy.make(scope, warnings); + Entrypoints entrypoints = com.ibm.wala.ipa.callgraph.impl.Util.makeMainEntrypoints(scope, cha, TestConstants.SLICE_TESTID); + AnalysisOptions options = CallGraphTestUtil.makeAnalysisOptions(scope, entrypoints); + + CallGraphBuilder builder = Util.makeZeroOneCFABuilder(options, cha, scope, warnings); + CallGraph cg = builder.makeCallGraph(options); + + CGNode main = findMainMethod(cg); + + Statement s = findCallToDoNothing(main); + System.err.println("Statement: " + s); + // compute a data slice + Collection slice = Slicer.computeBackwardSlice(s, cg, builder.getPointerAnalysis(), DataDependenceOptions.FULL, + ControlDependenceOptions.NONE); + dumpSlice(slice); + assertEquals(1, countAllocations(slice)); + } + + public void testTestArrays() throws ClassHierarchyException { + AnalysisScope scope = CallGraphTestUtil.makeJ2SEAnalysisScope(TestConstants.WALA_TESTDATA); + WarningSet warnings = new WarningSet(); + ClassHierarchy cha = ClassHierarchy.make(scope, warnings); + Entrypoints entrypoints = com.ibm.wala.ipa.callgraph.impl.Util.makeMainEntrypoints(scope, cha, TestConstants.SLICE_TESTARRAYS); + AnalysisOptions options = CallGraphTestUtil.makeAnalysisOptions(scope, entrypoints); + + CallGraphBuilder builder = Util.makeZeroOneCFABuilder(options, cha, scope, warnings); + CallGraph cg = builder.makeCallGraph(options); + + CGNode main = findMainMethod(cg); + + Statement s = findCallToDoNothing(main); + System.err.println("Statement: " + s); + // compute a data slice + Collection slice = Slicer.computeBackwardSlice(s, cg, builder.getPointerAnalysis(), DataDependenceOptions.FULL, + ControlDependenceOptions.NONE); + dumpSlice(slice); + assertEquals(2, countAllocations(slice)); + assertEquals(1, countAloads(slice)); + } + + public void testTestFields() throws ClassHierarchyException { + AnalysisScope scope = CallGraphTestUtil.makeJ2SEAnalysisScope(TestConstants.WALA_TESTDATA); + WarningSet warnings = new WarningSet(); + ClassHierarchy cha = ClassHierarchy.make(scope, warnings); + Entrypoints entrypoints = com.ibm.wala.ipa.callgraph.impl.Util.makeMainEntrypoints(scope, cha, TestConstants.SLICE_TESTFIELDS); + AnalysisOptions options = CallGraphTestUtil.makeAnalysisOptions(scope, entrypoints); + + CallGraphBuilder builder = Util.makeZeroOneCFABuilder(options, cha, scope, warnings); + CallGraph cg = builder.makeCallGraph(options); + + CGNode main = findMainMethod(cg); + + Statement s = findCallToDoNothing(main); + System.err.println("Statement: " + s); + // compute a data slice + Collection slice = Slicer.computeBackwardSlice(s, cg, builder.getPointerAnalysis(), DataDependenceOptions.FULL, + ControlDependenceOptions.NONE); + dumpSlice(slice); + assertEquals(2, countAllocations(slice)); + assertEquals(1, countPutfields(slice)); + } + + public void testThin1() throws ClassHierarchyException { + AnalysisScope scope = CallGraphTestUtil.makeJ2SEAnalysisScope(TestConstants.WALA_TESTDATA); + WarningSet warnings = new WarningSet(); + ClassHierarchy cha = ClassHierarchy.make(scope, warnings); + Entrypoints entrypoints = com.ibm.wala.ipa.callgraph.impl.Util.makeMainEntrypoints(scope, cha, TestConstants.SLICE_TESTTHIN1); + AnalysisOptions options = CallGraphTestUtil.makeAnalysisOptions(scope, entrypoints); + + CallGraphBuilder builder = Util.makeZeroOneCFABuilder(options, cha, scope, warnings); + CallGraph cg = builder.makeCallGraph(options); + + CGNode main = findMainMethod(cg); + + Statement s = findCallToDoNothing(main); + System.err.println("Statement: " + s); + + // compute normal data slice + // compute a data slice + Collection slice = Slicer.computeBackwardSlice(s, cg, builder.getPointerAnalysis(), DataDependenceOptions.FULL, + ControlDependenceOptions.NONE); + dumpSlice(slice); + assertEquals(3, countAllocations(slice)); + assertEquals(2, countPutfields(slice)); + + // compute thin slice .. ignore base pointers + slice = Slicer.computeBackwardSlice(s, cg, builder.getPointerAnalysis(), DataDependenceOptions.NO_BASE_PTRS, + ControlDependenceOptions.NONE); + dumpSlice(slice); + assertEquals(2, countAllocations(slice)); + assertEquals(1, countPutfields(slice)); + } + + public void testTestGlobal() throws ClassHierarchyException { + AnalysisScope scope = CallGraphTestUtil.makeJ2SEAnalysisScope(TestConstants.WALA_TESTDATA); + WarningSet warnings = new WarningSet(); + ClassHierarchy cha = ClassHierarchy.make(scope, warnings); + Entrypoints entrypoints = com.ibm.wala.ipa.callgraph.impl.Util.makeMainEntrypoints(scope, cha, TestConstants.SLICE_TESTGLOBAL); + AnalysisOptions options = CallGraphTestUtil.makeAnalysisOptions(scope, entrypoints); + + CallGraphBuilder builder = Util.makeZeroOneCFABuilder(options, cha, scope, warnings); + CallGraph cg = builder.makeCallGraph(options); + + CGNode main = findMainMethod(cg); + + Statement s = findCallToDoNothing(main); + System.err.println("Statement: " + s); + // compute a data slice + Collection slice = Slicer.computeBackwardSlice(s, cg, builder.getPointerAnalysis(), DataDependenceOptions.FULL, + ControlDependenceOptions.NONE); + dumpSlice(slice); + assertEquals(1, countAllocations(slice)); + assertEquals(2, countPutstatics(slice)); + assertEquals(2, countGetstatics(slice)); + } + + public void testTestMultiTarget() throws ClassHierarchyException { + AnalysisScope scope = CallGraphTestUtil.makeJ2SEAnalysisScope(TestConstants.WALA_TESTDATA); + WarningSet warnings = new WarningSet(); + ClassHierarchy cha = ClassHierarchy.make(scope, warnings); + Entrypoints entrypoints = com.ibm.wala.ipa.callgraph.impl.Util.makeMainEntrypoints(scope, cha, + TestConstants.SLICE_TESTMULTITARGET); + AnalysisOptions options = CallGraphTestUtil.makeAnalysisOptions(scope, entrypoints); + + CallGraphBuilder builder = Util.makeZeroOneCFABuilder(options, cha, scope, warnings); + CallGraph cg = builder.makeCallGraph(options); + + CGNode main = findMainMethod(cg); + + Statement s = findCallToDoNothing(main); + System.err.println("Statement: " + s); + // compute a data slice + Collection slice = Slicer.computeBackwardSlice(s, cg, builder.getPointerAnalysis(), DataDependenceOptions.FULL, + ControlDependenceOptions.NONE); + dumpSlice(slice); + assertEquals(2, countAllocations(slice)); + } + + public void testTestRecursion() throws ClassHierarchyException { + AnalysisScope scope = CallGraphTestUtil.makeJ2SEAnalysisScope(TestConstants.WALA_TESTDATA); + WarningSet warnings = new WarningSet(); + ClassHierarchy cha = ClassHierarchy.make(scope, warnings); + Entrypoints entrypoints = com.ibm.wala.ipa.callgraph.impl.Util.makeMainEntrypoints(scope, cha, + TestConstants.SLICE_TESTRECURSION); + AnalysisOptions options = CallGraphTestUtil.makeAnalysisOptions(scope, entrypoints); + + CallGraphBuilder builder = Util.makeZeroOneCFABuilder(options, cha, scope, warnings); + CallGraph cg = builder.makeCallGraph(options); + + CGNode main = findMainMethod(cg); + + Statement s = findCallToDoNothing(main); + System.err.println("Statement: " + s); + + // compute a data slice + Collection slice = Slicer.computeBackwardSlice(s, cg, builder.getPointerAnalysis(), DataDependenceOptions.FULL, + ControlDependenceOptions.NONE); + dumpSlice(slice); + assertEquals(3, countAllocations(slice)); + assertEquals(2, countPutfields(slice)); + } + + private int countAllocations(Collection slice) { + int count = 0; + for (Statement s : slice) { + if (s.getKind().equals(Statement.Kind.NORMAL)) { + NormalStatement ns = (NormalStatement) s; + if (ns.getInstruction() instanceof SSANewInstruction) { + count++; + } + } + } + return count; + } + + private int countAloads(Collection slice) { + int count = 0; + for (Statement s : slice) { + if (s.getKind().equals(Statement.Kind.NORMAL)) { + NormalStatement ns = (NormalStatement) s; + if (ns.getInstruction() instanceof SSAArrayLoadInstruction) { + count++; + } + } + } + return count; + } + + private int countConditionals(Collection slice) { + int count = 0; + for (Statement s : slice) { + if (s.getKind().equals(Statement.Kind.NORMAL)) { + NormalStatement ns = (NormalStatement) s; + if (ns.getInstruction() instanceof SSAConditionalBranchInstruction) { + count++; + } + } + } + return count; + } + + private int countPutfields(Collection slice) { + int count = 0; + for (Statement s : slice) { + if (s.getKind().equals(Statement.Kind.NORMAL)) { + NormalStatement ns = (NormalStatement) s; + if (ns.getInstruction() instanceof SSAPutInstruction) { + SSAPutInstruction p = (SSAPutInstruction) ns.getInstruction(); + if (!p.isStatic()) { + count++; + } + } + } + } + return count; + } + + private int countPutstatics(Collection slice) { + int count = 0; + for (Statement s : slice) { + if (s.getKind().equals(Statement.Kind.NORMAL)) { + NormalStatement ns = (NormalStatement) s; + if (ns.getInstruction() instanceof SSAPutInstruction) { + SSAPutInstruction p = (SSAPutInstruction) ns.getInstruction(); + if (p.isStatic()) { + count++; + } + } + } + } + return count; + } + + private int countGetstatics(Collection slice) { + int count = 0; + for (Statement s : slice) { + if (s.getKind().equals(Statement.Kind.NORMAL)) { + NormalStatement ns = (NormalStatement) s; + if (ns.getInstruction() instanceof SSAGetInstruction) { + SSAGetInstruction p = (SSAGetInstruction) ns.getInstruction(); + if (p.isStatic()) { + count++; + } + } + } + } + return count; + } + + public static void dumpSlice(Collection slice) { + dumpSlice(slice,new PrintWriter(System.err)); + } + + public static void dumpSlice(Collection slice, PrintWriter w) { + w.println("SLICE:\n"); + int i = 1; + for (Statement s : slice) { + String line = (i++) + " " + s; + w.println(line); + w.flush(); + } + } + + public static void dumpSliceToFile(Collection slice, String fileName) throws FileNotFoundException { + File f = new File(fileName); + FileOutputStream fo = new FileOutputStream(f); + PrintWriter w = new PrintWriter(fo); + dumpSlice(slice,w); + } + + public static CGNode findMainMethod(CallGraph cg) { + Descriptor d = Descriptor.findOrCreateUTF8("([Ljava/lang/String;)V"); + Atom name = Atom.findOrCreateUnicodeAtom("main"); + for (Iterator it = cg.getSuccNodes(cg.getFakeRootNode()); it.hasNext();) { + CGNode n = it.next(); + if (n.getMethod().getName().equals(name) && n.getMethod().getDescriptor().equals(d)) { + return n; + } + } + Assertions.UNREACHABLE("failed to find main() method"); + return null; + } + + + public static CGNode findMethod(CallGraph cg, String name) { + Atom a = Atom.findOrCreateUnicodeAtom(name); + for (Iterator it = cg.iterateNodes(); it.hasNext();) { + CGNode n = it.next(); + if (n.getMethod().getName().equals(a)) { + return n; + } + } + System.err.println("call graph " + cg); + Assertions.UNREACHABLE("failed to find method " + name); + return null; + } + + public static Statement findCallTo(CGNode n, String methodName) { + IR ir = n.getCallGraph().getInterpreter(n).getIR(n, new WarningSet()); + for (Iterator it = ir.iterateAllInstructions(); it.hasNext();) { + SSAInstruction s = it.next(); + if (s instanceof SSAInvokeInstruction) { + if (s.toString().indexOf(methodName) > -1) { + IntSet indices = ir.getCallInstructionIndices(((SSAInvokeInstruction) s).getCallSite()); + Assertions.productionAssertion(indices.size()== 1, "expected 1 but got " + indices.size()); + return new NormalStatement(n, indices.intIterator().next()); + } + } + } + Assertions.UNREACHABLE("failed to find call to " + methodName + " in " + n); + return null; + } + + private static Statement findCallToDoNothing(CGNode n) { + return findCallTo(n, "doNothing"); + } +} diff --git a/com.ibm.wala.core.tests/src/com/ibm/wala/core/tests/util/TestConstants.java b/com.ibm.wala.core.tests/src/com/ibm/wala/core/tests/util/TestConstants.java new file mode 100644 index 000000000..91b58e70b --- /dev/null +++ b/com.ibm.wala.core.tests/src/com/ibm/wala/core/tests/util/TestConstants.java @@ -0,0 +1,54 @@ +/******************************************************************************* + * Copyright (c) 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.core.tests.util; + +public interface TestConstants { + + public final static String WALA_TESTDATA = "wala.testdata.xml"; + + public static final String CLASSCONSTANT_MAIN = "LclassConstant/ClassConstant"; + public static final String PI_TEST_MAIN = "Lpi/PiNodeCallGraphTestCase"; + public static final String RECURSE_MAIN = "Lrecurse/NList"; + + public final static String HELLO = "hello.xml"; + public final static String HELLO_MAIN = "Lhello/Hello"; + + public final static String BCEL = "bcel.xml"; + public final static String BCEL_VERIFIER_MAIN = "Lorg/apache/bcel/verifier/Verifier"; + + public final static String JLEX = "JLex.xml"; + public final static String JLEX_MAIN = "LJLex/Main"; + + public final static String JAVA_CUP = "java_cup.xml"; + public final static String JAVA_CUP_MAIN = "Ljava_cup/Main"; + + public final static String MULTI_DIM_MAIN = "LmultiDim/TestMultiDim"; + + public final static String REFLECT1_MAIN = "Lreflection/Reflect1"; + + public final static String SLICE1_MAIN = "Lslice/Slice1"; + public final static String SLICE2_MAIN = "Lslice/Slice2"; + public final static String SLICE3_MAIN = "Lslice/Slice3"; + public final static String SLICE4_MAIN = "Lslice/Slice4"; + public final static String SLICE5_MAIN = "Lslice/Slice5"; + public final static String SLICE_TESTCD1 = "Lslice/TestCD1"; + public final static String SLICE_TESTCD2 = "Lslice/TestCD2"; + public final static String SLICE_TESTCD3 = "Lslice/TestCD3"; + public final static String SLICE_TESTID = "Lslice/TestId"; + public final static String SLICE_TESTARRAYS = "Lslice/TestArrays"; + public final static String SLICE_TESTFIELDS = "Lslice/TestFields"; + public final static String SLICE_TESTGLOBAL = "Lslice/TestGlobal"; + public final static String SLICE_TESTMULTITARGET = "Lslice/TestMultiTarget"; + public final static String SLICE_TESTRECURSION = "Lslice/TestRecursion"; + public final static String SLICE_TESTTHIN1 = "Lslice/TestThin1"; + + +} diff --git a/com.ibm.wala.core.tests/src/com/ibm/wala/core/tests/util/WalaTestCase.java b/com.ibm.wala.core.tests/src/com/ibm/wala/core/tests/util/WalaTestCase.java new file mode 100644 index 000000000..94d6891f2 --- /dev/null +++ b/com.ibm.wala.core.tests/src/com/ibm/wala/core/tests/util/WalaTestCase.java @@ -0,0 +1,100 @@ +/******************************************************************************* + * 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.core.tests.util; + +import junit.framework.TestCase; +import junit.framework.TestSuite; + +import com.ibm.wala.util.debug.Trace; +import com.ibm.wala.util.heapTrace.HeapTracer; + +/** + * + * Simple extension to JUnit test case. + * + * @author sfink + */ +public abstract class WalaTestCase extends TestCase { + + final private static boolean ANALYZE_LEAKS = false; + + public static boolean useShortProfile() { + String profile = System.getProperty("com.ibm.wala.junit.profile", "long"); + if (profile.equals("short")) { + return true; + } else { + return false; + } + } + + private String baseTraceFile; + + /* + * (non-Javadoc) + * + * @see junit.framework.TestCase#setUp() + */ + protected void setUp() throws Exception { + baseTraceFile = Trace.getTraceFile(); + if (baseTraceFile != null) { + Trace.setTraceFile(baseTraceFile + "." + getName()); + } + } + + /* + * (non-Javadoc) + * + * @see junit.framework.TestCase#tearDown() + */ + protected void tearDown() throws Exception { + if (baseTraceFile != null) { + Trace.setTraceFile(baseTraceFile); + } + if (ANALYZE_LEAKS) { + HeapTracer.analyzeLeaks(); + } + } + + public WalaTestCase() { + super("DomoTestCase"); + } + + /** + * Utility function: each DetoxTestCase subclass can have a main() method that + * calls this, to create a test suite consisting of just this test. Useful + * when investigating a single failing test. + */ + protected static void justThisTest(Class testClass) { + TestSuite suite = new TestSuite(testClass.getName()); + suite.addTestSuite(testClass); + junit.textui.TestRunner.run(suite); + } + + /** + * @param arg0 + */ + public WalaTestCase(String arg0) { + super(arg0); + } + + protected static void assertBound(String tag, double quantity, double bound) { + String msg = tag + ", quantity: " + quantity + ", bound:" + bound; + Trace.println(msg); + assertTrue(msg, quantity <= bound); + } + + protected static void assertBound(String tag, int quantity, int bound) { + String msg = tag + ", quantity: " + quantity + ", bound:" + bound; + Trace.println(msg); + assertTrue(msg, quantity <= bound); + } + +} diff --git a/com.ibm.wala.core.tests/src/com/ibm/wala/examples/analysis/SimpleThreadEscapeAnalysis.java b/com.ibm.wala.core.tests/src/com/ibm/wala/examples/analysis/SimpleThreadEscapeAnalysis.java new file mode 100644 index 000000000..1e1fc7aa9 --- /dev/null +++ b/com.ibm.wala.core.tests/src/com/ibm/wala/examples/analysis/SimpleThreadEscapeAnalysis.java @@ -0,0 +1,299 @@ +/******************************************************************************* + * Copyright (c) 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.examples.analysis; + +import com.ibm.wala.classLoader.*; +import com.ibm.wala.client.impl.*; +import com.ibm.wala.ipa.callgraph.*; +import com.ibm.wala.ipa.callgraph.impl.*; +import com.ibm.wala.ipa.callgraph.propagation.*; +import com.ibm.wala.ipa.cha.*; +import com.ibm.wala.types.*; +import com.ibm.wala.util.collections.HashSetFactory; +import com.ibm.wala.util.intset.*; + +import java.io.*; +import java.util.*; +import java.util.jar.*; + +/** + *

                    + * A simple thread-level escape analysis: this code computes the set of classes + * of which some instance may be accessed by some thread other than the one that + * created it. + *

                    + * + *

                    + * The algorithm is not very bright; it is based on the observation that there + * are only three ways for an object to pass from one thread to another. + *

                      + *
                    • The object is stored into a static variable. + *
                    • The object is stored into an instance field of a Thread + *
                    • The object is reachable from a field of another escaping object. + *
                    + *

                    + * + *

                    + * This observation is implemented in the obvious way: + *

                      + *
                    1. All static fields are collected + *
                    2. All Thread constructor parameters are collected + *
                    3. The points-to sets of these values represent the base set of escapees. + *
                    4. All object reachable from fields of these objects are added + *
                    5. This process continues until a fixpoint is reached + *
                    6. The abstract objects in the points-to sets are converted to types + *
                    7. This set of types is returned + *

                    + * + * @author Julian Dolby + */ +public class SimpleThreadEscapeAnalysis extends AbstractAnalysisEngine { + private final Set applicationJarFiles; + + private final String applicationMainClass; + + /** + * The two input parameters define the program to analyze: the jars of .class + * files and the main class to start from. + */ + public SimpleThreadEscapeAnalysis(Set applicationJarFiles, String applicationMainClass) { + this.applicationJarFiles = applicationJarFiles; + this.applicationMainClass = applicationMainClass; + } + + /** + * Given a root path, add it to the set if it is a jar, or traverse it + * recursively if it is a directory. + */ + private void collectJars(File f, Set result) throws IOException { + if (f.isDirectory()) { + File[] files = f.listFiles(); + for (int i = 0; i < files.length; i++) { + collectJars(files[i], result); + } + } else if (f.getAbsolutePath().endsWith(".jar")) { + result.add(new JarFile(f)); + } + } + + /** + * Collect the set of JarFiles that constitute the system libraries of the + * running JRE. + */ + private JarFile[] getSystemJars() throws IOException { + Set jarFiles = HashSetFactory.make(); + + String javaHomePath = System.getProperty("java.home"); + + if (!javaHomePath.endsWith(File.separator)) { + javaHomePath = javaHomePath + File.separator; + } + + collectJars(new File(javaHomePath + "lib"), jarFiles); + + return jarFiles.toArray(new JarFile[jarFiles.size()]); + } + + /** + * Take the given set of JarFiles that constitute the program, and return a + * set of Module files as expected by the WALA machinery. + */ + private Set getModuleFiles() { + Set result = HashSetFactory.make(); + for (Iterator jars = applicationJarFiles.iterator(); jars.hasNext();) { + result.add(new JarFileModule(jars.next())); + } + + return result; + } + + /** + * The heart of the analysis. + */ + public Set gatherThreadEscapingClasses() throws IOException, ClassHierarchyException { + + // + // set the application to analyze + // + setModuleFiles(getModuleFiles()); + + // + // set the system jar files to use. + // change this if you want to use a specific jre version + // + setJ2SELibraries(getSystemJars()); + + // + // the application and libraries are set, now build the scope... + // + buildAnalysisScope(); + + // + // ...and the class hierarchy + // + ClassHierarchy cha = buildClassHierarchy(); + setClassHierarchy(cha); + + // + // select the call graph construction algorithm + // change this if greater precision is desired + // (see com.ibm.wala.client.impl.*BuilderFactory) + // + setCallGraphBuilderFactory(new ZeroCFABuilderFactory()); + + // + // entrypoints are where analysis starts + // + Entrypoints roots = Util.makeMainEntrypoints(getScope(), cha, applicationMainClass); + + // + // analysis options controls aspects of call graph construction + // + AnalysisOptions options = getDefaultOptions(roots); + + // + // build the call graph + // + buildCallGraph(cha, options, true); + + // + // extract data for analysis + // + CallGraph cg = getCallGraph(); + PointerAnalysis pa = getPointerAnalysis(); + + // + // collect all places where objects can escape their creating thread: + // 1) all static fields + // 2) arguments to Thread constructors + // + Set escapeAnalysisRoots = HashSetFactory.make(); + HeapModel heapModel = pa.getHeapModel(); + + // 1) static fields + for (Iterator clss = cha.iterateAllClasses(); clss.hasNext();) { + IClass cls = (IClass) clss.next(); + Collection staticFields = cls.getDeclaredStaticFields(); + for (Iterator sfs = staticFields.iterator(); sfs.hasNext();) { + IField sf = (IField) sfs.next(); + if (sf.getFieldTypeReference().isReferenceType()) { + escapeAnalysisRoots.add(heapModel.getPointerKeyForStaticField(sf)); + } + } + } + + // 2) instance fields of Threads + // (we hack this by getting the 'this' parameter of all ctor calls; + // this works because the next phase will add all objects transitively + // reachable from fields of types in these pointer keys, and all + // Thread objects must be constructed somewhere) + Collection threads = cha.computeSubClasses(TypeReference.JavaLangThread); + for (Iteratorclss = threads.iterator(); clss.hasNext();) { + IClass cls = (IClass) clss.next(); + for (Iterator ms = cls.getDeclaredMethods(); ms.hasNext();) { + IMethod m = (IMethod) ms.next(); + if (m.isInit()) { + Set nodes = cg.getNodes(m.getReference()); + for (Iterator ns = nodes.iterator(); ns.hasNext();) { + CGNode n = (CGNode) ns.next(); + escapeAnalysisRoots.add(heapModel.getPointerKeyForLocal(n, 1)); + } + } + } + } + + // + // compute escaping types: all types flowing to escaping roots and + // all types transitively reachable through their fields. + // + Set escapingInstanceKeys = HashSetFactory.make(); + + // + // pass 1: get abstract objects (instance keys) for escaping locations + // + for (Iterator rts = escapeAnalysisRoots.iterator(); rts.hasNext();) { + PointerKey root = rts.next(); + OrdinalSet objects = pa.getPointsToSet(root); + for (Iterator objs = objects.iterator(); objs.hasNext();) { + InstanceKey obj = (InstanceKey) objs.next(); + escapingInstanceKeys.add(obj); + } + } + + // + // passes 2+: get fields of escaping keys, and add pointed-to keys + // + Set newKeys = HashSetFactory.make(); + do { + newKeys.clear(); + for (Iterator keys = escapingInstanceKeys.iterator(); keys.hasNext();) { + InstanceKey key = keys.next(); + IClass type = key.getConcreteType(); + if (type.isReferenceType()) { + if (type.isArrayClass()) { + if (((ArrayClass) type).getElementClass() != null) { + PointerKey fk = heapModel.getPointerKeyForArrayContents(key); + OrdinalSet fobjects = pa.getPointsToSet(fk); + for (Iterator fobjs = fobjects.iterator(); fobjs.hasNext();) { + InstanceKey fobj = (InstanceKey) fobjs.next(); + if (!escapingInstanceKeys.contains(fobj)) { + newKeys.add(fobj); + } + } + } + } else { + Collection fields = type.getAllInstanceFields(); + for (Iterator fs = fields.iterator(); fs.hasNext();) { + IField f = (IField) fs.next(); + if (f.getFieldTypeReference().isReferenceType()) { + PointerKey fk = heapModel.getPointerKeyForInstanceField(key, f); + OrdinalSet fobjects = pa.getPointsToSet(fk); + for (Iterator fobjs = fobjects.iterator(); fobjs.hasNext();) { + InstanceKey fobj = (InstanceKey) fobjs.next(); + if (!escapingInstanceKeys.contains(fobj)) { + newKeys.add(fobj); + } + } + } + } + } + } + } + escapingInstanceKeys.addAll(newKeys); + } while (!newKeys.isEmpty()); + + // + // get set of types from set of instance keys + // + Set escapingTypes = HashSetFactory.make(); + for (Iterator keys = escapingInstanceKeys.iterator(); keys.hasNext();) { + InstanceKey key = keys.next(); + escapingTypes.add(key.getConcreteType()); + } + + return escapingTypes; + } + + public static void main(String[] args) throws IOException, ClassHierarchyException { + String mainClassName = args[0]; + + Set jars = HashSetFactory.make(); + for (int i = 1; i < args.length; i++) { + jars.add(new JarFile(args[i])); + } + + Set escapingTypes = (new SimpleThreadEscapeAnalysis(jars, mainClassName)).gatherThreadEscapingClasses(); + + for (Iterator types = escapingTypes.iterator(); types.hasNext();) { + System.out.println(types.next().getName().toString()); + } + } +} diff --git a/com.ibm.wala.core.tests/src/com/ibm/wala/examples/drivers/ExportCallGraphToXML.java b/com.ibm.wala.core.tests/src/com/ibm/wala/examples/drivers/ExportCallGraphToXML.java new file mode 100644 index 000000000..245ce812d --- /dev/null +++ b/com.ibm.wala.core.tests/src/com/ibm/wala/examples/drivers/ExportCallGraphToXML.java @@ -0,0 +1,225 @@ +/******************************************************************************* + * 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.examples.drivers; + +import java.io.File; +import java.util.Collection; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Properties; + +import org.eclipse.emf.ecore.EObject; + +import com.ibm.wala.ecore.java.ECallSite; +import com.ibm.wala.ecore.java.EJavaClass; +import com.ibm.wala.ecore.java.EJavaMethod; +import com.ibm.wala.ecore.java.callGraph.ECallGraph; +import com.ibm.wala.ecore.java.scope.EJavaAnalysisScope; +import com.ibm.wala.emf.wrappers.EMFBridge; +import com.ibm.wala.emf.wrappers.EMFScopeWrapper; +import com.ibm.wala.emf.wrappers.EObjectDictionary; +import com.ibm.wala.emf.wrappers.EObjectGraph; +import com.ibm.wala.emf.wrappers.EObjectGraphImpl; +import com.ibm.wala.emf.wrappers.EUtil; +import com.ibm.wala.emf.wrappers.JavaScopeUtil; +import com.ibm.wala.ipa.callgraph.AnalysisOptions; +import com.ibm.wala.ipa.callgraph.CallGraph; +import com.ibm.wala.ipa.callgraph.Entrypoints; +import com.ibm.wala.ipa.callgraph.impl.Util; +import com.ibm.wala.ipa.cha.ClassHierarchy; +import com.ibm.wala.properties.WalaProperties; +import com.ibm.wala.util.collections.Iterator2Collection; +import com.ibm.wala.util.debug.Assertions; +import com.ibm.wala.util.warnings.WalaException; +import com.ibm.wala.util.warnings.WarningSet; + +/** + * This simple example application builds a call graph writes it to an XML file + * + * @author sfink + */ +public class ExportCallGraphToXML { + + /** + * Usage: ExportCallGraphToXML -appJar [jar file name] The "jar file name" + * should be something like "c:/temp/testdata/java_cup.jar" + * + * @param args + */ + public static void main(String[] args) { + run(args); + } + + /** + * Usage: args = "-appJar [jar file name] " The "jar file name" should be + * something like "c:/temp/testdata/java_cup.jar" + * + * @param args + */ + public static void run(String[] args) { + validateCommandLine(args); + run(args[1]); + } + + /** + * @param appJar + * something like "c:/temp/testdata/java_cup.jar" + */ + public static void run(String appJar) { + try { + + EJavaAnalysisScope escope = JavaScopeUtil.makeAnalysisScope(appJar); + + // generate a DOMO-consumable wrapper around the incoming scope object + EMFScopeWrapper scope = EMFScopeWrapper.generateScope(escope); + + // TODO: return the warning set (need a CAPA type) + // invoke DOMO to build a DOMO class hierarchy object + WarningSet warnings = new WarningSet(); + System.err.println("Build class hierarchy..."); + ClassHierarchy cha = ClassHierarchy.make(scope, warnings); + + Entrypoints entrypoints = com.ibm.wala.ipa.callgraph.impl.Util.makeMainEntrypoints(scope, cha); + AnalysisOptions options = new AnalysisOptions(scope, entrypoints); + + // // + // build the call graph + // // + System.err.println("Build callgraph..."); + com.ibm.wala.ipa.callgraph.CallGraphBuilder builder = Util.makeZeroCFABuilder(options, cha, scope, warnings, null, null); + CallGraph cg = builder.makeCallGraph(options); + + System.err.println("Convert to EMF..."); + com.ibm.wala.emf.wrappers.ECallGraphWrapper ccg = EMFBridge.makeCallGraph(cg); + ECallGraph ecg = (ECallGraph) ccg.export(); + + Properties p = null; + ; + try { + p = WalaProperties.loadProperties(); + } catch (WalaException e) { + e.printStackTrace(); + Assertions.UNREACHABLE(); + } + String filename = p.getProperty(WalaProperties.OUTPUT_DIR) + File.separatorChar + "cg.xml"; + System.err.println("Writing to file: " + filename); + write(ecg, filename); + + // try and load it too + + List l = EUtil.readEObjects(filename, ExportCallGraphToXML.class.getClassLoader()); + + // convert it to a default graph for kicks + ECallGraph output = (ECallGraph) l.get(0); + System.err.println(output.getClass()); + EObjectGraph graph = EObjectGraphImpl.fromEMF(output); + System.err.println("read " + graph.getNumberOfNodes() + " nodes"); + + } catch (WalaException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + + @SuppressWarnings("unchecked") + private static void write(ECallGraph cg, String filename) throws WalaException { + + // make sure every java method reachable from the call graph + // is a node is the call graph + Collection c = new Iterator2Collection(cg.getNodes().getContents().iterator()); + for (Iterator it = c.iterator(); it.hasNext();) { + Object node = it.next(); + if (node instanceof ECallSite) { + ECallSite site = (ECallSite) node; + EJavaMethod method = site.getDeclaredTarget(); + if (!c.contains(method)) { + cg.getNodes().getContents().add(method); + } + + method = site.getJavaMethod(); + if (!c.contains(method)) { + cg.getNodes().getContents().add(method); + } + } + } + + // make a canonical dictionary of all method nodes + EObjectDictionary methodNodes = new EObjectDictionary(); + for (Iterator it = cg.getNodes().getContents().iterator(); it.hasNext();) { + Object node = it.next(); + if (node instanceof EJavaMethod) { + EJavaMethod method = (EJavaMethod) node; + methodNodes.findOrAdd(method); + } + } + + // Create a collection of EObjects to persist + Collection persist = new LinkedList(); + // Persist the call graph itself + persist.add(cg); + // Persist the nodes of the call graph which are NOT contained in the + // ECallGraph + persist.add(cg.getNodes()); + + // Persist all Java classes reachable from the call graph, + // and make sure pointers are canonical + EObjectDictionary klasses = new EObjectDictionary(); + for (Iterator it = cg.getNodes().getContents().iterator(); it.hasNext();) { + Object node = it.next(); + if (node instanceof ECallSite) { + ECallSite site = (ECallSite) node; + EJavaMethod method = (EJavaMethod) site.getDeclaredTarget(); + method = (EJavaMethod) methodNodes.findOrAdd(method); + site.setDeclaredTarget(method); + EJavaClass klass = (EJavaClass) klasses.findOrAdd(method.getJavaClass()); + method.setJavaClass(klass); + + method = site.getJavaMethod(); + method = (EJavaMethod) methodNodes.findOrAdd(method); + site.setJavaMethod(method); + klass = (EJavaClass) klasses.findOrAdd(method.getJavaClass()); + method.setJavaClass(klass); + } else if (node instanceof EJavaMethod) { + EJavaMethod method = (EJavaMethod) node; + EJavaClass klass = (EJavaClass) klasses.findOrAdd(method.getJavaClass()); + method.setJavaClass(klass); + } else { + Assertions.UNREACHABLE("Unexpected type " + node.getClass()); + } + } + persist.add(klasses.export(true)); + + // Save everything to a file. + EUtil.saveToFile(persist, filename); + } + + /** + * Validate that the command-line arguments obey the expected usage. + * + * Usage: + *
                      + *
                    • args[0] : "-appJar" + *
                    • args[1] : something like "c:/temp/testdata/java_cup.jar" g = GVTypeHierarchy.typeHierarchy2Graph(th); + g = GVTypeHierarchy.pruneForAppLoader(g); + if (g.getNumberOfNodes() == 0) { + System.err.println("ERROR: The type hierarchy in " + ExportTypeHierarchyToXML.getFileName() + " has no nodes from the Application loader"); + System.err.println("Probably something's wrong with the input jars being analyzed."); + System.err.println("check the files in the path: " + classpath); + System.err.println("Also look at these warning messages:"); + System.err.println(warnings.toString()); + System.exit(-1); + } + + } catch (WalaException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + + private static void write(ETypeHierarchy t, String filename) throws WalaException { + + if (filename == null) { + throw new WalaException("internal error: null filename parameter"); + } + + // Create a collection of EObjects to persist + Collection persist = new LinkedList(); + // Persist the type hierarchy itself + persist.add(t); + // Persist the classes as well, which are NOT contained in the ETypeHierarchy + persist.add(t.getClasses().getNodes()); + // Persist the interfaces as well, which are NOT contained in the ETypeHierarchy + persist.add(t.getInterfaces().getNodes()); + + // Save everything to a file. + EUtil.saveToFile(persist, filename); + } + + static String getFileName() throws WalaException { + Properties p = null;; + try { + p = WalaProperties.loadProperties(); + } catch (WalaException e) { + e.printStackTrace(); + Assertions.UNREACHABLE(); + } + String file = p.getProperty(WalaProperties.OUTPUT_DIR) + File.separatorChar + FILENAME; + return file; + } + + public static ETypeHierarchy buildTypeHierarchy(String classpath, WarningSet warnings) throws WalaException { + EJavaAnalysisScope escope = JavaScopeUtil.makeAnalysisScope(classpath); + + // generate a WALA-consumable wrapper around the incoming scope object + EMFScopeWrapper scope = EMFScopeWrapper.generateScope(escope); + + // invoke WALA to build a class hierarchy + ClassHierarchy cha = ClassHierarchy.make(scope, warnings); + + // Export the class hierarchy object to an EMF TypeHierarchy object + com.ibm.wala.emf.wrappers.ETypeHierarchyWrapper t1 = EMFBridge.makeTypeHierarchy(cha); + + ETypeHierarchy th = (ETypeHierarchy) t1.toEMF(); + return th; + } + + /** + * Validate that the command-line arguments obey the expected usage. + * + * Usage: args[0] : "-classpath" args[1] : String, a ";"-delimited class path + * + * @param args + * @throws UnsupportedOperationException + * if command-line is malformed. + */ + static void validateCommandLine(String[] args) { + if (args.length < 2) { + throw new UnsupportedOperationException("must have at least 2 command-line arguments"); + } + if (!args[0].equals("-classpath")) { + throw new UnsupportedOperationException("invalid command-line, args[0] should be -classpath, but is " + args[0]); + } + } +} \ No newline at end of file diff --git a/com.ibm.wala.core.tests/src/com/ibm/wala/examples/drivers/GVCallGraph.java b/com.ibm.wala.core.tests/src/com/ibm/wala/examples/drivers/GVCallGraph.java new file mode 100644 index 000000000..43d420e18 --- /dev/null +++ b/com.ibm.wala.core.tests/src/com/ibm/wala/examples/drivers/GVCallGraph.java @@ -0,0 +1,186 @@ +/******************************************************************************* + * 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.examples.drivers; + +import java.io.File; +import java.util.Properties; + +import com.ibm.wala.ecore.java.scope.EJavaAnalysisScope; +import com.ibm.wala.emf.wrappers.EMFScopeWrapper; +import com.ibm.wala.emf.wrappers.JavaScopeUtil; +import com.ibm.wala.examples.properties.WalaExamplesProperties; +import com.ibm.wala.ipa.callgraph.AnalysisOptions; +import com.ibm.wala.ipa.callgraph.CGNode; +import com.ibm.wala.ipa.callgraph.CallGraph; +import com.ibm.wala.ipa.callgraph.Entrypoints; +import com.ibm.wala.ipa.callgraph.impl.Util; +import com.ibm.wala.ipa.callgraph.propagation.LocalPointerKey; +import com.ibm.wala.ipa.cha.ClassHierarchy; +import com.ibm.wala.properties.WalaProperties; +import com.ibm.wala.types.ClassLoaderReference; +import com.ibm.wala.util.collections.Filter; +import com.ibm.wala.util.debug.Assertions; +import com.ibm.wala.util.graph.Graph; +import com.ibm.wala.util.io.CommandLine; +import com.ibm.wala.util.warnings.WalaException; +import com.ibm.wala.util.warnings.WarningSet; +import com.ibm.wala.viz.DotUtil; +import com.ibm.wala.viz.GVUtil; + +/** + * + * This simple example WALA application builds a call graph and fires off + * ghostview to viz a DOT representation. + * + * @author sfink + */ +public class GVCallGraph { + + private final static String PS_FILE = "cg.ps"; + + /** + * Usage: GVCallGraph -appJar [jar file name] The "jar file name" should + * be something like "c:/temp/testdata/java_cup.jar" + * + * @param args + */ + public static void main(String[] args) { + run(args); + } + + /** + * Usage: args = "-appJar [jar file name] " The "jar file name" should be + * something like "c:/temp/testdata/java_cup.jar" + * + * @param args + */ + public static Process run(String[] args) { + Properties p = CommandLine.parse(args); + validateCommandLine(p); + return run(p.getProperty("appJar")); + } + + /** + * @param appJar + * something like "c:/temp/testdata/java_cup.jar" + */ + public static Process run(String appJar) { + try { + + Graph g = buildPrunedCallGraph(appJar); + + Properties p = null; + try { + p = WalaExamplesProperties.loadProperties(); + p.putAll(WalaProperties.loadProperties()); + } catch (WalaException e) { + e.printStackTrace(); + Assertions.UNREACHABLE(); + } + String psFile = p.getProperty(WalaProperties.OUTPUT_DIR) + File.separatorChar + PS_FILE; + + String dotExe = p.getProperty(WalaExamplesProperties.DOT_EXE); + DotUtil.dotify(g, null, GVTypeHierarchy.DOT_FILE, psFile, dotExe); + + String gvExe = p.getProperty(WalaExamplesProperties.GHOSTVIEW_EXE); + return GVUtil.launchGV(psFile, gvExe); + + } catch (WalaException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + return null; + } + } + + /** + * @param appJar + * something like "c:/temp/testdata/java_cup.jar" + * @return a call graph + * @throws WalaException + */ + public static Graph buildPrunedCallGraph(String appJar) throws WalaException { + EJavaAnalysisScope escope = JavaScopeUtil.makeAnalysisScope(appJar); + + // generate a DOMO-consumable wrapper around the incoming scope object + EMFScopeWrapper scope = EMFScopeWrapper.generateScope(escope); + + + // TODO: return the warning set (need a CAPA type) + // invoke DOMO to build a DOMO class hierarchy object + WarningSet warnings = new WarningSet(); + ClassHierarchy cha = ClassHierarchy.make(scope, warnings); + + Entrypoints entrypoints = com.ibm.wala.ipa.callgraph.impl.Util.makeMainEntrypoints(scope, cha); + AnalysisOptions options = new AnalysisOptions(scope, entrypoints); + + // // + // build the call graph + // // + com.ibm.wala.ipa.callgraph.CallGraphBuilder builder = Util.makeZeroCFABuilder(options, cha, scope, warnings, null, null); + CallGraph cg = builder.makeCallGraph(options); + + Graph g = pruneForAppLoader(cg); + return g; + } + + static Graph pruneForAppLoader(CallGraph g) throws WalaException { + return GVTypeHierarchy.pruneGraph(g, new ApplicationLoaderFilter()); + } + + /** + * Validate that the command-line arguments obey the expected usage. + * + * Usage: + *
                        + *
                      • args[0] : "-appJar" + *
                      • args[1] : something like "c:/temp/testdata/java_cup.jar" + *
                      • CGNode + *
                      • LocalPointerKey + *
                      + */ + private static class ApplicationLoaderFilter implements Filter { + + /* + * (non-Javadoc) + * + * @see com.ibm.capa.util.collections.Filter#accepts(java.lang.Object) + */ + public boolean accepts(Object o) { + if (o instanceof CGNode) { + CGNode n = (CGNode) o; + return n.getMethod().getDeclaringClass().getClassLoader().getReference().equals(ClassLoaderReference.Application); + } else if (o instanceof LocalPointerKey) { + LocalPointerKey l = (LocalPointerKey) o; + return accepts(l.getNode()); + } else { + return false; + } + } + + } +} \ No newline at end of file diff --git a/com.ibm.wala.core.tests/src/com/ibm/wala/examples/drivers/GVControlDependenceGraph.java b/com.ibm.wala.core.tests/src/com/ibm/wala/examples/drivers/GVControlDependenceGraph.java new file mode 100644 index 000000000..967d1bb80 --- /dev/null +++ b/com.ibm.wala.core.tests/src/com/ibm/wala/examples/drivers/GVControlDependenceGraph.java @@ -0,0 +1,159 @@ +/******************************************************************************* + * 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.examples.drivers; + +import java.io.File; +import java.util.Properties; + +import com.ibm.wala.cfg.cdg.ControlDependenceGraph; +import com.ibm.wala.classLoader.IMethod; +import com.ibm.wala.ecore.java.scope.EJavaAnalysisScope; +import com.ibm.wala.emf.wrappers.EMFScopeWrapper; +import com.ibm.wala.emf.wrappers.JavaScopeUtil; +import com.ibm.wala.examples.properties.WalaExamplesProperties; +import com.ibm.wala.ipa.callgraph.AnalysisOptions; +import com.ibm.wala.ipa.callgraph.impl.Everywhere; +import com.ibm.wala.ipa.cha.ClassHierarchy; +import com.ibm.wala.properties.WalaProperties; +import com.ibm.wala.ssa.IR; +import com.ibm.wala.types.MethodReference; +import com.ibm.wala.util.StringStuff; +import com.ibm.wala.util.debug.Assertions; +import com.ibm.wala.util.warnings.WalaException; +import com.ibm.wala.util.warnings.WarningSet; +import com.ibm.wala.viz.DotUtil; +import com.ibm.wala.viz.GVUtil; +import com.ibm.wala.viz.GhostviewUtil; + +/** + * + * This simple example application builds a WALA CDG and fires off ghostview + * to viz a DOT representation. + * + * @author sfink + */ +public class GVControlDependenceGraph { + + final public static boolean SANITIZE_CFG = false; + + final public static String PS_FILE = "cdg.ps"; + + /** + * Usage: GVControlDependenceGraph -appJar [jar file name] -sig [method signature] The "jar + * file name" should be something like "c:/temp/testdata/java_cup.jar" The + * signature should be something like "java_cup.lexer.advance()V" + * + * @param args + */ + public static void main(String[] args) { + + run(args); + } + + /** + * @param args + * -appJar [jar file name] -sig [method signature] The "jar file + * name" should be something like "c:/temp/testdata/java_cup.jar" The + * signature should be something like "java_cup.lexer.advance()V" + */ + public static Process run(String[] args) { + validateCommandLine(args); + return run(args[1], args[3]); + } + + /** + * @param appJar + * should be something like "c:/temp/testdata/java_cup.jar" + * @param methodSig + * should be something like "java_cup.lexer.advance()V" + */ + public static Process run(String appJar, String methodSig) { + try { + if (SWTCallGraph.isDirectory(appJar)) { + appJar = SWTCallGraph.findJarFiles(new String[] { appJar }); + } + EJavaAnalysisScope escope = JavaScopeUtil.makeAnalysisScope(appJar); + + // generate a DOMO-consumable wrapper around the incoming scope object + EMFScopeWrapper scope = EMFScopeWrapper.generateScope(escope); + + // invoke DOMO to build a DOMO class hierarchy object + WarningSet warnings = new WarningSet(); + ClassHierarchy cha = ClassHierarchy.make(scope, warnings); + + MethodReference mr = StringStuff.makeMethodReference(methodSig); + + IMethod m = cha.resolveMethod(mr); + if (m == null) { + Assertions.UNREACHABLE("could not resolve " + mr); + } + AnalysisOptions options = new AnalysisOptions(); + options.getSSAOptions().setUsePiNodes(true); + IR ir = options.getSSACache().findOrCreateIR(m, Everywhere.EVERYWHERE, cha, options.getSSAOptions(), new WarningSet()); + + if (ir == null) { + Assertions.UNREACHABLE("Null IR for " + m); + } + + System.err.println(ir.toString()); + ControlDependenceGraph cdg = new ControlDependenceGraph(ir.getControlFlowGraph()); + + Properties wp = null; + try { + wp = WalaProperties.loadProperties(); + wp.putAll(WalaExamplesProperties.loadProperties()); + } catch (WalaException e) { + e.printStackTrace(); + Assertions.UNREACHABLE(); + } + String psFile = wp.getProperty(WalaProperties.OUTPUT_DIR) + File.separatorChar + GVControlDependenceGraph.PS_FILE; + String dotFile = wp.getProperty(WalaProperties.OUTPUT_DIR) + File.separatorChar + + GVTypeHierarchy.DOT_FILE; + String dotExe = wp.getProperty(WalaExamplesProperties.DOT_EXE); + String gvExe = wp.getProperty(WalaExamplesProperties.GHOSTVIEW_EXE); + + DotUtil.dotify(cdg, GhostviewUtil.makeIRDecorator(ir), dotFile, psFile, dotExe); + + return GVUtil.launchGV(psFile, gvExe); + + } catch (WalaException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + return null; + } + } + + /** + * Validate that the command-line arguments obey the expected usage. + * + * Usage: + *
                        + *
                      • args[0] : "-appJar" + *
                      • args[1] : something like "c:/temp/testdata/java_cup.jar" + *
                      • args[2] : "-sig" + *
                      • args[3] : a method signature like "java_cup.lexer.advance()V" g = pruneSDG(sdg); + DotUtil.dotify(g, makeNodeDecorator(), GVTypeHierarchy.DOT_FILE, psFile, dotExe); + + String gvExe = p.getProperty(WalaExamplesProperties.GHOSTVIEW_EXE); + return GVUtil.launchGV(psFile, gvExe); + + } catch (WalaException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + return null; + } + } + + private static Graph pruneSDG(SDG sdg) { + Filter f = new Filter() { + public boolean accepts(Object o) { + Statement s = (Statement)o; + if (s.getNode().equals(s.getNode().getCallGraph().getFakeRootNode())) { + return false; + } else { + return true; + } + } + }; + return GraphSlicer.prune(sdg, f); + } + + private static NodeDecorator makeNodeDecorator() { + return new NodeDecorator() { + public String getLabel(Object o) throws WalaException { + Statement s = (Statement) o; + switch (s.getKind()) { + case HEAP_PARAM_CALLEE: + case HEAP_PARAM_CALLER: + case HEAP_RET_CALLEE: + case HEAP_RET_CALLER: + HeapStatement h =(HeapStatement)s; + return s.getKind() + "\\n" + h.getNode() + "\\n" + h.getLocation(); + case EXC_RET_CALLEE: + case EXC_RET_CALLER: + case NORMAL: + case NORMAL_RET_CALLEE: + case NORMAL_RET_CALLER: + case PARAM_CALLEE: + case PARAM_CALLER: + case PHI: + default: + return s.toString(); + } + } + + }; + } + + /** + * Validate that the command-line arguments obey the expected usage. + * + * Usage: + *
                          + *
                        • args[0] : "-appJar" + *
                        • args[1] : something like "c:/temp/testdata/java_cup.jar" + *
                        • args[2] : "-mainClass" + *
                        • args[3] : something like "Lslice/TestRecursion" + * + * @throws UnsupportedOperationException + * if command-line is malformed. + */ + static void validateCommandLine(Properties p) { + if (p.get("appJar") == null) { + throw new UnsupportedOperationException("expected command-line to include -appJar"); + } + if (p.get("mainClass") == null) { + throw new UnsupportedOperationException("expected command-line to include -appJar"); + } + } +} \ No newline at end of file diff --git a/com.ibm.wala.core.tests/src/com/ibm/wala/examples/drivers/GVSlice.java b/com.ibm.wala.core.tests/src/com/ibm/wala/examples/drivers/GVSlice.java new file mode 100644 index 000000000..bfb231727 --- /dev/null +++ b/com.ibm.wala.core.tests/src/com/ibm/wala/examples/drivers/GVSlice.java @@ -0,0 +1,259 @@ +/******************************************************************************* + * 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.examples.drivers; + +import java.io.File; +import java.util.Collection; +import java.util.Properties; + +import com.ibm.wala.core.tests.callGraph.CallGraphTestUtil; +import com.ibm.wala.core.tests.slicer.SlicerTest; +import com.ibm.wala.ecore.java.scope.EJavaAnalysisScope; +import com.ibm.wala.emf.wrappers.EMFScopeWrapper; +import com.ibm.wala.emf.wrappers.JavaScopeUtil; +import com.ibm.wala.examples.properties.WalaExamplesProperties; +import com.ibm.wala.ipa.callgraph.AnalysisOptions; +import com.ibm.wala.ipa.callgraph.CGNode; +import com.ibm.wala.ipa.callgraph.CallGraph; +import com.ibm.wala.ipa.callgraph.CallGraphBuilder; +import com.ibm.wala.ipa.callgraph.Entrypoints; +import com.ibm.wala.ipa.callgraph.impl.Util; +import com.ibm.wala.ipa.cha.ClassHierarchy; +import com.ibm.wala.ipa.slicer.HeapStatement; +import com.ibm.wala.ipa.slicer.NormalStatement; +import com.ibm.wala.ipa.slicer.ParamStatement; +import com.ibm.wala.ipa.slicer.SDG; +import com.ibm.wala.ipa.slicer.Slicer; +import com.ibm.wala.ipa.slicer.Statement; +import com.ibm.wala.ipa.slicer.ParamStatement.CallStatementCarrier; +import com.ibm.wala.ipa.slicer.ParamStatement.ValueNumberCarrier; +import com.ibm.wala.ipa.slicer.Slicer.ControlDependenceOptions; +import com.ibm.wala.ipa.slicer.Slicer.DataDependenceOptions; +import com.ibm.wala.ipa.slicer.Statement.Kind; +import com.ibm.wala.properties.WalaProperties; +import com.ibm.wala.ssa.SSAInstruction; +import com.ibm.wala.ssa.SSAInvokeInstruction; +import com.ibm.wala.util.collections.Filter; +import com.ibm.wala.util.debug.Assertions; +import com.ibm.wala.util.graph.Graph; +import com.ibm.wala.util.graph.GraphIntegrity; +import com.ibm.wala.util.graph.GraphSlicer; +import com.ibm.wala.util.graph.NodeDecorator; +import com.ibm.wala.util.graph.GraphIntegrity.UnsoundGraphException; +import com.ibm.wala.util.io.CommandLine; +import com.ibm.wala.util.warnings.WalaException; +import com.ibm.wala.util.warnings.WarningSet; +import com.ibm.wala.viz.DotUtil; +import com.ibm.wala.viz.GVUtil; + +/** + * + * This simple example WALA application builds an SDG and fires off ghostview to + * viz a DOT representation of a slice in the SDG + * + * @author sfink + */ +public class GVSlice { + + private final static String PS_FILE = "slice.ps"; + + /** + * Usage: GVSDG -appJar [jar file name] -mainclass [main class] -src [method + * name] + * + * The "jar file name" should be something like + * "c:/temp/testdata/java_cup.jar" + * + * @param args + */ + public static void main(String[] args) { + run(args); + } + + /** + */ + public static Process run(String[] args) { + Properties p = CommandLine.parse(args); + validateCommandLine(p); + return run(p.getProperty("appJar"), p.getProperty("mainClass"), p.getProperty("srcCaller"), p.getProperty("srcCallee"), + goBackward(p), GVSDG.getDataDependenceOptions(p), GVSDG.getControlDependenceOptions(p)); + } + + private static boolean goBackward(Properties p) { + return !p.getProperty("dir","backward").equals("forward"); + } + + /** + */ + public static Process run(String appJar, String mainClass, String srcCaller, String srcCallee, boolean goBackward, DataDependenceOptions dOptions, + ControlDependenceOptions cOptions) { + try { + EJavaAnalysisScope escope = JavaScopeUtil.makeAnalysisScope(appJar); + + // generate a WALA-consumable wrapper around the incoming scope object + EMFScopeWrapper scope = EMFScopeWrapper.generateScope(escope); + WarningSet warnings = new WarningSet(); + ClassHierarchy cha = ClassHierarchy.make(scope, warnings); + Entrypoints entrypoints = com.ibm.wala.ipa.callgraph.impl.Util.makeMainEntrypoints(scope, cha, mainClass); + AnalysisOptions options = CallGraphTestUtil.makeAnalysisOptions(scope, entrypoints); + + CallGraphBuilder builder = Util.makeZeroOneCFABuilder(options, cha, scope, warnings); + CallGraph cg = builder.makeCallGraph(options); + SDG sdg = new SDG(cg, builder.getPointerAnalysis(), dOptions, cOptions); + + CGNode main = SlicerTest.findMethod(cg, srcCaller); + Statement s = SlicerTest.findCallTo(main, srcCallee); + System.err.println("Statement: " + s); + Collection slice = null; + if (goBackward) { + slice = Slicer.computeBackwardSlice(s, cg, builder.getPointerAnalysis(), dOptions, cOptions); + } else { + // for forward slices ... we actually slice from the return value of calls. + s = getReturnStatementForCall(s); + slice = Slicer.computeForwardSlice(s, cg, builder.getPointerAnalysis(), dOptions, cOptions); + } + SlicerTest.dumpSlice(slice); + + Graph g = pruneSDG(sdg, slice); + try { + GraphIntegrity.check(g); + } catch (UnsoundGraphException e1) { + e1.printStackTrace(); + Assertions.UNREACHABLE(); + } + Assertions.productionAssertion(g.getNumberOfNodes() == slice.size(), "panic " + g.getNumberOfNodes() + " " + slice.size()); + + Properties p = null; + try { + p = WalaExamplesProperties.loadProperties(); + p.putAll(WalaProperties.loadProperties()); + } catch (WalaException e) { + e.printStackTrace(); + Assertions.UNREACHABLE(); + } + String psFile = p.getProperty(WalaProperties.OUTPUT_DIR) + File.separatorChar + PS_FILE; + + String dotExe = p.getProperty(WalaExamplesProperties.DOT_EXE); + + DotUtil.dotify(g, makeNodeDecorator(), GVTypeHierarchy.DOT_FILE, psFile, dotExe); + + String gvExe = p.getProperty(WalaExamplesProperties.GHOSTVIEW_EXE); + return GVUtil.launchGV(psFile, gvExe); + + } catch (WalaException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + return null; + } + } + + /** + * If s is a call statement, return the statement representing the normal return from s + */ + public static Statement getReturnStatementForCall(Statement s) { + if (s.getKind() == Kind.NORMAL) { + SSAInstruction st = ((NormalStatement)s).getInstruction(); + if (st instanceof SSAInvokeInstruction) { + return new ParamStatement.NormalReturnCaller(s.getNode(),(SSAInvokeInstruction)st); + } else { + return s; + } + } else { + return s; + } + } + + public static Graph pruneSDG(SDG sdg, final Collection slice) { + Filter f = new Filter() { + public boolean accepts(Object o) { + return slice.contains(o); + } + }; + return GraphSlicer.prune(sdg, f); + } + + public static NodeDecorator makeNodeDecorator() { + return new NodeDecorator() { + public String getLabel(Object o) throws WalaException { + Statement s = (Statement) o; + switch (s.getKind()) { + case HEAP_PARAM_CALLEE: + case HEAP_PARAM_CALLER: + case HEAP_RET_CALLEE: + case HEAP_RET_CALLER: + HeapStatement h = (HeapStatement) s; + return s.getKind() + "\\n" + h.getNode() + "\\n" + h.getLocation(); + case NORMAL: + NormalStatement n = (NormalStatement) s; + return n.getNode() + "\\n" + n.getInstruction(); + case PARAM_CALLEE: + case PARAM_CALLER: + if (s instanceof ValueNumberCarrier) { + ValueNumberCarrier vc = (ValueNumberCarrier) s; + if (s instanceof CallStatementCarrier) { + CallStatementCarrier cc = (CallStatementCarrier) s; + return s.getKind() + "\\n" + s.getNode() + "\\n" + cc.getCall() + "\\nv" + vc.getValueNumber(); + } else { + return s.getKind() + "\\n" + s.getNode() + "\\nv" + vc.getValueNumber(); + } + } else { + if (s instanceof CallStatementCarrier) { + CallStatementCarrier cc = (CallStatementCarrier) s; + return s.getKind() + "\\n" + s.getNode() + "\\n" + cc.getCall(); + } else { + return s.toString(); + } + } + case EXC_RET_CALLEE: + case EXC_RET_CALLER: + case NORMAL_RET_CALLEE: + case NORMAL_RET_CALLER: + case PHI: + default: + return s.toString(); + } + } + + }; + } + + /** + * Validate that the command-line arguments obey the expected usage. + * + * Usage: + *
                            + *
                          • args[0] : "-appJar" + *
                          • args[1] : something like "c:/temp/testdata/java_cup.jar" + *
                          • args[2] : "-mainClass" + *
                          • args[3] : something like "Lslice/TestRecursion" * + *
                          • args[4] : "-srcCallee" + *
                          • args[5] : something like "print" * + *
                          • args[4] : "-srcCaller" + *
                          • args[5] : something like "main" + * + * @throws UnsupportedOperationException + * if command-line is malformed. + */ + static void validateCommandLine(Properties p) { + if (p.get("appJar") == null) { + throw new UnsupportedOperationException("expected command-line to include -appJar"); + } + if (p.get("mainClass") == null) { + throw new UnsupportedOperationException("expected command-line to include -mainClass"); + } + if (p.get("srcCallee") == null) { + throw new UnsupportedOperationException("expected command-line to include -srcCallee"); + } + if (p.get("srcCaller") == null) { + throw new UnsupportedOperationException("expected command-line to include -srcCaller"); + } + } +} \ No newline at end of file diff --git a/com.ibm.wala.core.tests/src/com/ibm/wala/examples/drivers/GVTypeHierarchy.java b/com.ibm.wala.core.tests/src/com/ibm/wala/examples/drivers/GVTypeHierarchy.java new file mode 100644 index 000000000..7583f6330 --- /dev/null +++ b/com.ibm.wala.core.tests/src/com/ibm/wala/examples/drivers/GVTypeHierarchy.java @@ -0,0 +1,156 @@ +/******************************************************************************* + * 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.examples.drivers; + +import java.io.File; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; +import java.util.Properties; + +import org.eclipse.emf.ecore.EObject; + +import com.ibm.wala.ecore.java.EClassLoaderName; +import com.ibm.wala.ecore.java.EJavaClass; +import com.ibm.wala.ecore.java.ETypeHierarchy; +import com.ibm.wala.emf.wrappers.EObjectGraphImpl; +import com.ibm.wala.emf.wrappers.ETypeHierarchyWrapper; +import com.ibm.wala.emf.wrappers.EUtil; +import com.ibm.wala.examples.properties.WalaExamplesProperties; +import com.ibm.wala.properties.WalaProperties; +import com.ibm.wala.util.CollectionFilter; +import com.ibm.wala.util.collections.Filter; +import com.ibm.wala.util.debug.Assertions; +import com.ibm.wala.util.graph.Graph; +import com.ibm.wala.util.graph.GraphSlicer; +import com.ibm.wala.util.warnings.WalaException; +import com.ibm.wala.util.warnings.WarningSet; +import com.ibm.wala.viz.DotUtil; +import com.ibm.wala.viz.GVUtil; + +/** + * + * This simple example WALA application builds a TypeHierarchy and fires off + * ghostview to viz a DOT representation. + * + * @author sfink + */ +public class GVTypeHierarchy { + + public final static String DOT_FILE = "temp.dt"; + + private final static String PS_FILE = "th.ps"; + + public static Properties p; + + static { + try { + p = WalaProperties.loadProperties(); + p.putAll(WalaExamplesProperties.loadProperties()); + } catch (WalaException e) { + e.printStackTrace(); + Assertions.UNREACHABLE(); + } + + } + + public static void main(String[] args) { + run(args, false); + } + + public static Process run(String[] args, boolean readFromFile) { + try { + ETypeHierarchy th = null; + if (readFromFile) { + th = readTypeHierarchy(); + } else { + ExportTypeHierarchyToXML.validateCommandLine(args); + String classpath = args[ExportTypeHierarchyToXML.CLASSPATH_INDEX]; + th = ExportTypeHierarchyToXML.buildTypeHierarchy(classpath, new WarningSet()); + } + + Graph g = typeHierarchy2Graph(th); + + g = pruneForAppLoader(g); + String dotFile = p.getProperty(WalaProperties.OUTPUT_DIR) + File.separatorChar + DOT_FILE; + String psFile = p.getProperty(WalaProperties.OUTPUT_DIR) + File.separatorChar + PS_FILE; + String dotExe = p.getProperty(WalaExamplesProperties.DOT_EXE); + String gvExe = p.getProperty(WalaExamplesProperties.GHOSTVIEW_EXE); + DotUtil.dotify(g, null, dotFile, psFile, dotExe); + return GVUtil.launchGV(psFile, gvExe); + + } catch (WalaException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + return null; + } + } + + /* + * (non-Javadoc) + * + * @see com.ibm.capa.core.EAnalysisEngine#processImpl() + */ + public static Graph typeHierarchy2Graph(ETypeHierarchy et) throws WalaException { + ETypeHierarchyWrapper t = new ETypeHierarchyWrapper(et); + EObjectGraphImpl dg = new EObjectGraphImpl(); + for (Iterator it = t.getClasses().iterateNodes(); it.hasNext();) { + dg.addNode(it.next()); + } + for (Iterator it = t.getInterfaces().iterateNodes(); it.hasNext();) { + dg.addNode(it.next()); + } + for (Iterator it = t.getClasses().iterateNodes(); it.hasNext();) { + EJavaClass x = (EJavaClass) it.next(); + for (Iterator it2 = t.getClasses().getSuccNodes(x); it2.hasNext();) { + dg.addEdge(x, it2.next()); + } + for (Iterator it2 = t.getImplements(x).iterator(); it2.hasNext();) { + dg.addEdge(it2.next(), x); + } + } + for (Iterator it = t.getInterfaces().iterateNodes(); it.hasNext();) { + EJavaClass x = (EJavaClass) it.next(); + for (Iterator it2 = t.getInterfaces().getSuccNodes(x); it2.hasNext();) { + dg.addEdge(x, it2.next()); + } + } + + return dg; + } + + static Graph pruneForAppLoader(Graph g) throws WalaException { + Filter f = new Filter() { + public boolean accepts(Object o) { + if (o instanceof EJavaClass) { + EJavaClass klass = (EJavaClass) o; + return (klass.getLoader().equals(EClassLoaderName.APPLICATION_LITERAL)); + } else { + return false; + } + } + }; + + return pruneGraph(g, f); + } + + public static Graph pruneGraph(Graph g, Filter f) throws WalaException { + + Collection slice = GraphSlicer.slice(g, f); + return GraphSlicer.prune(g, new CollectionFilter(slice)); + } + + static ETypeHierarchy readTypeHierarchy() throws WalaException { + + List l = EUtil.readEObjects(ExportTypeHierarchyToXML.getFileName(), ExportTypeHierarchyToXML.class.getClassLoader()); + return (ETypeHierarchy) l.get(0); + } +} \ No newline at end of file diff --git a/com.ibm.wala.core.tests/src/com/ibm/wala/examples/drivers/GVWalaIR.java b/com.ibm.wala.core.tests/src/com/ibm/wala/examples/drivers/GVWalaIR.java new file mode 100644 index 000000000..ee6be019d --- /dev/null +++ b/com.ibm.wala.core.tests/src/com/ibm/wala/examples/drivers/GVWalaIR.java @@ -0,0 +1,152 @@ +/******************************************************************************* + * 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.examples.drivers; + +import java.io.File; +import java.util.Properties; + +import com.ibm.wala.classLoader.IMethod; +import com.ibm.wala.ecore.java.scope.EJavaAnalysisScope; +import com.ibm.wala.emf.wrappers.EMFScopeWrapper; +import com.ibm.wala.emf.wrappers.JavaScopeUtil; +import com.ibm.wala.examples.properties.WalaExamplesProperties; +import com.ibm.wala.ipa.callgraph.AnalysisOptions; +import com.ibm.wala.ipa.callgraph.impl.Everywhere; +import com.ibm.wala.ipa.cha.ClassHierarchy; +import com.ibm.wala.properties.WalaProperties; +import com.ibm.wala.ssa.IR; +import com.ibm.wala.types.MethodReference; +import com.ibm.wala.util.StringStuff; +import com.ibm.wala.util.debug.Assertions; +import com.ibm.wala.util.warnings.WalaException; +import com.ibm.wala.util.warnings.WarningSet; +import com.ibm.wala.viz.GhostviewUtil; + +/** + * + * This simple example application builds a WALA IR and fires off ghostview + * to viz a DOT representation. + * + * @author sfink + */ +public class GVWalaIR { + + final public static boolean SANITIZE_CFG = false; + + final public static String PS_FILE = "ir.ps"; + + /** + * Usage: GVWalaIR -appJar [jar file name] -sig [method signature] The "jar + * file name" should be something like "c:/temp/testdata/java_cup.jar" The + * signature should be something like "java_cup.lexer.advance()V" + * + * @param args + */ + public static void main(String[] args) { + run(args); + } + + /** + * @param args + * -appJar [jar file name] -sig [method signature] The "jar file + * name" should be something like "c:/temp/testdata/java_cup.jar" The + * signature should be something like "java_cup.lexer.advance()V" + */ + public static Process run(String[] args) { + validateCommandLine(args); + return run(args[1], args[3]); + } + + /** + * @param appJar + * should be something like "c:/temp/testdata/java_cup.jar" + * @param methodSig + * should be something like "java_cup.lexer.advance()V" + */ + public static Process run(String appJar, String methodSig) { + try { + if (SWTCallGraph.isDirectory(appJar)) { + appJar = SWTCallGraph.findJarFiles(new String[] { appJar }); + } + EJavaAnalysisScope escope = JavaScopeUtil.makeAnalysisScope(appJar); + + // generate a DOMO-consumable wrapper around the incoming scope object + EMFScopeWrapper scope = EMFScopeWrapper.generateScope(escope); + + // invoke DOMO to build a DOMO class hierarchy object + WarningSet warnings = new WarningSet(); + ClassHierarchy cha = ClassHierarchy.make(scope, warnings); + + MethodReference mr = StringStuff.makeMethodReference(methodSig); + + IMethod m = cha.resolveMethod(mr); + if (m == null) { + Assertions.UNREACHABLE("could not resolve " + mr); + } + AnalysisOptions options = new AnalysisOptions(); + options.getSSAOptions().setUsePiNodes(true); + IR ir = options.getSSACache().findOrCreateIR(m, Everywhere.EVERYWHERE, cha, options.getSSAOptions(), new WarningSet()); + + if (ir == null) { + Assertions.UNREACHABLE("Null IR for " + m); + } + + System.err.println(ir.toString()); + + Properties wp = null; + try { + wp = WalaProperties.loadProperties(); + wp.putAll(WalaExamplesProperties.loadProperties()); + } catch (WalaException e) { + e.printStackTrace(); + Assertions.UNREACHABLE(); + } + String psFile = wp.getProperty(WalaProperties.OUTPUT_DIR) + File.separatorChar + GVWalaIR.PS_FILE; + String dotFile = wp.getProperty(WalaProperties.OUTPUT_DIR) + File.separatorChar + + GVTypeHierarchy.DOT_FILE; + String dotExe = wp.getProperty(WalaExamplesProperties.DOT_EXE); + String gvExe = wp.getProperty(WalaExamplesProperties.GHOSTVIEW_EXE); + + return GhostviewUtil.ghostviewIR(cha, ir, SANITIZE_CFG, psFile, dotFile, dotExe, gvExe); + + } catch (WalaException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + return null; + } + } + + /** + * Validate that the command-line arguments obey the expected usage. + * + * Usage: + *
                              + *
                            • args[0] : "-appJar" + *
                            • args[1] : something like "c:/temp/testdata/java_cup.jar" + *
                            • args[2] : "-sig" + *
                            • args[3] : a method signature like "java_cup.lexer.advance()V" m = Environment.readEnv(); + + for (Iterator> it = m.entrySet().iterator(); it.hasNext();) { + System.out.println(it.next()); + } + } catch (WalaException e) { + e.printStackTrace(); + } + } +} diff --git a/com.ibm.wala.core.tests/src/com/ibm/wala/examples/drivers/SWTCallGraph.java b/com.ibm.wala.core.tests/src/com/ibm/wala/examples/drivers/SWTCallGraph.java new file mode 100644 index 000000000..45a1235a1 --- /dev/null +++ b/com.ibm.wala.core.tests/src/com/ibm/wala/examples/drivers/SWTCallGraph.java @@ -0,0 +1,198 @@ +/******************************************************************************* + * 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.examples.drivers; + +import java.io.File; +import java.util.Collection; +import java.util.Iterator; +import java.util.Properties; + +import org.eclipse.jface.window.ApplicationWindow; + +import com.ibm.wala.ecore.java.scope.EJavaAnalysisScope; +import com.ibm.wala.emf.wrappers.EMFScopeWrapper; +import com.ibm.wala.emf.wrappers.JavaScopeUtil; +import com.ibm.wala.examples.properties.WalaExamplesProperties; +import com.ibm.wala.ipa.callgraph.AnalysisOptions; +import com.ibm.wala.ipa.callgraph.CallGraph; +import com.ibm.wala.ipa.callgraph.CallGraphStats; +import com.ibm.wala.ipa.callgraph.Entrypoints; +import com.ibm.wala.ipa.callgraph.impl.Util; +import com.ibm.wala.ipa.cha.ClassHierarchy; +import com.ibm.wala.properties.WalaProperties; +import com.ibm.wala.util.collections.HashSetFactory; +import com.ibm.wala.util.debug.Assertions; +import com.ibm.wala.util.graph.GraphIntegrity; +import com.ibm.wala.util.graph.InferGraphRootsImpl; +import com.ibm.wala.util.io.CommandLine; +import com.ibm.wala.util.io.FileUtil; +import com.ibm.wala.util.perf.EngineTimings; +import com.ibm.wala.util.warnings.WalaException; +import com.ibm.wala.util.warnings.WarningSet; +import com.ibm.wala.viz.SWTTreeViewer; +import com.ibm.wala.viz.ViewIRAction; + +/** + * + * This application is a WALA client: it invokes an SWT TreeViewer to visualize + * a Call Graph + * + * @author sfink + */ +public class SWTCallGraph { + + private final static boolean CHECK_GRAPH = false; + + /** + * Usage: SWTCallGraph -appJar [jar file name] + * + * The "jar file name" should be something like + * "c:/temp/testdata/java_cup.jar" + * + * If it's a directory, then we'll try to find all jar files under that + * directory. + * + * @param args + * @throws WalaException + */ + public static void main(String[] args) throws WalaException { + Properties p = CommandLine.parse(args); + GVCallGraph.validateCommandLine(p); + run(p); + } + + /** + * @param p + * should contain at least the following properties: + *
                                + *
                              • appJar should be something like + * "c:/temp/testdata/java_cup.jar" + *
                              • algorithm (optional) can be one of: + *
                                  + *
                                • "ZERO_CFA" (default value) + *
                                • "RTA" + *
                                + *
                              + * + * @throws WalaException + */ + public static ApplicationWindow run(Properties p) throws WalaException { + + try { + String appJar = p.getProperty("appJar"); + if (isDirectory(appJar)) { + appJar = SWTCallGraph.findJarFiles(new String[] { appJar }); + } + EJavaAnalysisScope escope = JavaScopeUtil.makeAnalysisScope(appJar); + + String exclusionFile = p.getProperty("exclusions"); + if (exclusionFile != null) { + escope.setExclusionFileName(exclusionFile); + } + + // generate a DOMO-consumable wrapper around the incoming scope object + EMFScopeWrapper scope = EMFScopeWrapper.generateScope(escope); + + // TODO: return the warning set (need a CAPA type) + // invoke DOMO to build a DOMO class hierarchy object + WarningSet warnings = new WarningSet(); + ClassHierarchy cha = ClassHierarchy.make(scope, warnings); + + Entrypoints entrypoints = com.ibm.wala.ipa.callgraph.impl.Util.makeMainEntrypoints(scope, cha); + AnalysisOptions options = new AnalysisOptions(scope, entrypoints); + + // // + // build the call graph + // // + com.ibm.wala.ipa.callgraph.CallGraphBuilder builder = Util.makeZeroCFABuilder(options, cha, scope, warnings, null, null); + CallGraph cg = builder.makeCallGraph(options); + + System.out.println(CallGraphStats.getStats(cg)); + + if (CHECK_GRAPH) { + GraphIntegrity.check(cg); + } + + Properties wp = null; + try { + wp = WalaProperties.loadProperties(); + wp.putAll(WalaExamplesProperties.loadProperties()); + } catch (WalaException e) { + e.printStackTrace(); + Assertions.UNREACHABLE(); + } + String psFile = wp.getProperty(WalaProperties.OUTPUT_DIR) + File.separatorChar + GVWalaIR.PS_FILE; + String dotFile = wp.getProperty(WalaProperties.OUTPUT_DIR) + File.separatorChar + GVTypeHierarchy.DOT_FILE; + String dotExe = wp.getProperty(WalaExamplesProperties.DOT_EXE); + String gvExe = wp.getProperty(WalaExamplesProperties.GHOSTVIEW_EXE); + + // create and run the viewer + final SWTTreeViewer v = new SWTTreeViewer(); + v.setGraphInput(cg); + v.setRootsInput(InferGraphRootsImpl.inferRoots(cg)); + v.getPopUpActions().add(new ViewIRAction(v, cg, psFile, dotFile, dotExe, gvExe)); + v.run(); + return v.getApplicationWindow(); + + } catch (Exception e) { + e.printStackTrace(); + return null; + } finally { + EngineTimings.report(); + } + } + + // private static CallGraphConstructionAlgorithm chooseAlgorithm(Properties p) + // throws CapaException { + // String alg = p.getProperty("algorithm", "ZERO_CFA"); + // if (alg.equals("ZERO_CFA")) { + // return CallGraphConstructionAlgorithm.ZERO_CFA_LITERAL; + // } else if (alg.equals("RTA")) { + // return CallGraphConstructionAlgorithm.RTA_LITERAL; + // } else if (alg.equals("ZERO_ONE_CFA")) { + // return CallGraphConstructionAlgorithm.VANILLA_ZERO_ONE_CFA_LITERAL; + // } else { + // throw new CapaException("Unsupported algorithm: " + alg); + // } + // } + + static boolean isDirectory(String appJar) { + return (new File(appJar).isDirectory()); + } + + static String findJarFiles(String[] directories) throws WalaException { + Collection result = HashSetFactory.make(); + for (int i = 0; i < directories.length; i++) { + for (Iterator it = FileUtil.listFiles(directories[i], ".*\\.jar", true).iterator(); it.hasNext();) { + File f = (File) it.next(); + result.add(f.getAbsolutePath()); + } + } + return composeString(result); + } + + /** + * @param s + * Collection + */ + private static String composeString(Collection s) { + StringBuffer result = new StringBuffer(); + Iterator it = s.iterator(); + for (int i = 0; i < s.size() - 1; i++) { + result.append(it.next()); + result.append(';'); + } + if (it.hasNext()) { + result.append(it.next()); + } + return result.toString(); + } +} \ No newline at end of file diff --git a/com.ibm.wala.core.tests/src/com/ibm/wala/examples/drivers/SWTPointsTo.java b/com.ibm.wala.core.tests/src/com/ibm/wala/examples/drivers/SWTPointsTo.java new file mode 100644 index 000000000..ad78d888b --- /dev/null +++ b/com.ibm.wala.core.tests/src/com/ibm/wala/examples/drivers/SWTPointsTo.java @@ -0,0 +1,100 @@ +/******************************************************************************* + * 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.examples.drivers; + +import java.util.Properties; + +import org.eclipse.jface.window.ApplicationWindow; + +import com.ibm.wala.analysis.pointers.BasicHeapGraph; +import com.ibm.wala.ecore.java.scope.EJavaAnalysisScope; +import com.ibm.wala.emf.wrappers.EMFScopeWrapper; +import com.ibm.wala.emf.wrappers.JavaScopeUtil; +import com.ibm.wala.ipa.callgraph.AnalysisOptions; +import com.ibm.wala.ipa.callgraph.CallGraph; +import com.ibm.wala.ipa.callgraph.Entrypoints; +import com.ibm.wala.ipa.callgraph.impl.Util; +import com.ibm.wala.ipa.callgraph.propagation.PointerAnalysis; +import com.ibm.wala.ipa.cha.ClassHierarchy; +import com.ibm.wala.util.graph.Graph; +import com.ibm.wala.util.graph.InferGraphRootsImpl; +import com.ibm.wala.util.io.CommandLine; +import com.ibm.wala.util.warnings.WalaException; +import com.ibm.wala.util.warnings.WarningSet; +import com.ibm.wala.viz.SWTTreeViewer; + +/** + * + * This application is a WALA client: it invokes an SWT TreeViewer to visualize + * a Points-To solution + * + * @author sfink + */ +public class SWTPointsTo { + + /** + * Usage: SWTPointsTo -appJar [jar file name] The "jar file name" should be + * something like "c:/temp/testdata/java_cup.jar" + * + * @param args + */ + public static void main(String[] args) { + Properties p = CommandLine.parse(args); + GVCallGraph.validateCommandLine(p); + run(p.getProperty("appJar")); + } + + /** + * @param appJar + * should be something like "c:/temp/testdata/java_cup.jar" + */ + public static ApplicationWindow run(String appJar) { + + try { + Graph g = buildPointsTo(appJar); + + // create and run the viewer + final SWTTreeViewer v = new SWTTreeViewer(); + v.setGraphInput(g); + v.setRootsInput(InferGraphRootsImpl.inferRoots(g)); + v.run(); + return v.getApplicationWindow(); + + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } + + public static Graph buildPointsTo(String appJar) throws WalaException { + EJavaAnalysisScope escope = JavaScopeUtil.makeAnalysisScope(appJar); + + // generate a DOMO-consumable wrapper around the incoming scope object + EMFScopeWrapper scope = EMFScopeWrapper.generateScope(escope); + + + // TODO: return the warning set (need a CAPA type) + // invoke DOMO to build a DOMO class hierarchy object + WarningSet warnings = new WarningSet(); + ClassHierarchy cha = ClassHierarchy.make(scope, warnings); + + Entrypoints entrypoints = com.ibm.wala.ipa.callgraph.impl.Util.makeMainEntrypoints(scope, cha); + AnalysisOptions options = new AnalysisOptions(scope, entrypoints); + + // // + // build the call graph + // // + com.ibm.wala.ipa.callgraph.CallGraphBuilder builder = Util.makeZeroCFABuilder(options, cha, scope, warnings, null, null); + CallGraph cg = builder.makeCallGraph(options); + PointerAnalysis pointerAnalysis = builder.getPointerAnalysis(); + return new BasicHeapGraph(pointerAnalysis,cg); + } +} \ No newline at end of file diff --git a/com.ibm.wala.core.tests/src/com/ibm/wala/examples/drivers/SWTTypeHierarchy.java b/com.ibm.wala.core.tests/src/com/ibm/wala/examples/drivers/SWTTypeHierarchy.java new file mode 100644 index 000000000..51b80d45c --- /dev/null +++ b/com.ibm.wala.core.tests/src/com/ibm/wala/examples/drivers/SWTTypeHierarchy.java @@ -0,0 +1,75 @@ +/******************************************************************************* + * 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.examples.drivers; + +import java.util.Collection; + +import org.eclipse.emf.ecore.EObject; +import org.eclipse.jface.window.ApplicationWindow; + +import com.ibm.wala.ecore.java.ETypeHierarchy; +import com.ibm.wala.util.graph.Graph; +import com.ibm.wala.util.graph.InferGraphRootsImpl; +import com.ibm.wala.viz.SWTTreeViewer; + +/** + * + * This application is a WALA client: it invokes an SWT TreeViewer to visualize + * a TypeHierarchy in a precomputed file serialized on disk. So, you must run + * ExportTypeHierarchyToXML before running this, to compute the type hierarchy and + * serialize it to disk. + * + * @author sfink + */ +public class SWTTypeHierarchy { + + /** + * Usage: SWTTreeViewerBasicPipeline + */ + public static void main(String[] args) { + run(); + } + + public static ApplicationWindow run() { + + try { + ETypeHierarchy th = GVTypeHierarchy.readTypeHierarchy(); + if (th.getClasses().getNodes().getContents().size() <1) { + System.err.println("PANIC: th # classes=" + th.getClasses().getNodes().getContents().size()); + System.exit(-1); + } + + Graph g = GVTypeHierarchy.typeHierarchy2Graph(th); + g = GVTypeHierarchy.pruneForAppLoader(g); + + if (g.getNumberOfNodes() == 0) { + System.err.println("ERROR: The type hierarchy in " + ExportTypeHierarchyToXML.getFileName() + " has no nodes from the Application loader"); + System.exit(-1); + } + + // create and run the viewer + final SWTTreeViewer v =new SWTTreeViewer(); + v.setGraphInput(g); + Collection roots = InferGraphRootsImpl.inferRoots(g); + if (roots.size() < 1) { + System.err.println("PANIC: roots.size()=" + roots.size()); + System.exit(-1); + } + v.setRootsInput(roots); + v.run(); + return v.getApplicationWindow(); + + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } +} \ No newline at end of file diff --git a/com.ibm.wala.core.tests/src/com/ibm/wala/examples/properties/WalaExamplesProperties.java b/com.ibm.wala.core.tests/src/com/ibm/wala/examples/properties/WalaExamplesProperties.java new file mode 100644 index 000000000..d84770800 --- /dev/null +++ b/com.ibm.wala.core.tests/src/com/ibm/wala/examples/properties/WalaExamplesProperties.java @@ -0,0 +1,50 @@ +/******************************************************************************* + * 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.examples.properties; + +import java.io.File; +import java.net.URL; +import java.util.Properties; + +import com.ibm.wala.properties.WalaProperties; +import com.ibm.wala.util.config.FileProvider; +import com.ibm.wala.util.warnings.WalaException; + +public final class WalaExamplesProperties { + + public static final String GHOSTVIEW_EXE = "ghostview_exe"; //$NON-NLS-1$ + + public static final String DOT_EXE = "dot_exe"; //$NON-NLS-1$ + + public final static String PROPERTY_FILENAME = "wala.examples.properties"; //$NON-NLS-1$ + + public static Properties loadProperties() throws WalaException { + + try { + Properties result = WalaProperties.loadPropertiesFromFile(PROPERTY_FILENAME); + + return result; + } catch (Exception e) { + e.printStackTrace(); + throw new WalaException("Unable to set up wala examples properties ", e); + } + } + + public static String getWalaCoreTestsHomeDirectory() throws WalaException { + final URL url = WalaExamplesProperties.class.getClassLoader().getResource(PROPERTY_FILENAME); + if (url == null) { + throw new WalaException("failed to find URL for capa.examples.properties"); + } + + return new File(FileProvider.filePathFromURL(url)).getParentFile().getParentFile().getAbsolutePath(); + } + +} \ No newline at end of file diff --git a/com.ibm.wala.eclipse.tests/.classpath b/com.ibm.wala.eclipse.tests/.classpath new file mode 100644 index 000000000..021596729 --- /dev/null +++ b/com.ibm.wala.eclipse.tests/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/com.ibm.wala.eclipse.tests/.project b/com.ibm.wala.eclipse.tests/.project new file mode 100644 index 000000000..7caeccc39 --- /dev/null +++ b/com.ibm.wala.eclipse.tests/.project @@ -0,0 +1,28 @@ + + + com.ibm.wala.eclipse.tests + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/com.ibm.wala.eclipse.tests/.settings/org.eclipse.jdt.core.prefs b/com.ibm.wala.eclipse.tests/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 000000000..d3a810263 --- /dev/null +++ b/com.ibm.wala.eclipse.tests/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,12 @@ +#Tue Oct 10 11:07:28 EDT 2006 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5 +org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve +org.eclipse.jdt.core.compiler.compliance=1.5 +org.eclipse.jdt.core.compiler.debug.lineNumber=generate +org.eclipse.jdt.core.compiler.debug.localVariable=generate +org.eclipse.jdt.core.compiler.debug.sourceFile=generate +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.source=1.5 diff --git a/com.ibm.wala.eclipse.tests/.settings/org.eclipse.jdt.ui.prefs b/com.ibm.wala.eclipse.tests/.settings/org.eclipse.jdt.ui.prefs new file mode 100644 index 000000000..9991bec92 --- /dev/null +++ b/com.ibm.wala.eclipse.tests/.settings/org.eclipse.jdt.ui.prefs @@ -0,0 +1,3 @@ +#Tue Oct 10 11:07:28 EDT 2006 +eclipse.preferences.version=1 +internal.default.compliance=default diff --git a/com.ibm.wala.eclipse.tests/META-INF/MANIFEST.MF b/com.ibm.wala.eclipse.tests/META-INF/MANIFEST.MF new file mode 100644 index 000000000..3cb99fd5d --- /dev/null +++ b/com.ibm.wala.eclipse.tests/META-INF/MANIFEST.MF @@ -0,0 +1,17 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Tests Plug-in +Bundle-SymbolicName: com.ibm.wala.eclipse.tests +Bundle-Version: 1.0.0 +Bundle-Activator: com.ibm.wala.eclipse.tests.Activator +Bundle-Vendor: IBM +Bundle-Localization: plugin +Require-Bundle: org.eclipse.ui, + org.eclipse.core.runtime, + org.eclipse.core.resources, + org.eclipse.jdt.core, + org.eclipse.ui.ide, + org.junit, + com.ibm.wala.core, + com.ibm.wala.eclipse +Eclipse-LazyStart: true diff --git a/com.ibm.wala.eclipse.tests/build.properties b/com.ibm.wala.eclipse.tests/build.properties new file mode 100644 index 000000000..41eb6ade2 --- /dev/null +++ b/com.ibm.wala.eclipse.tests/build.properties @@ -0,0 +1,4 @@ +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + . diff --git a/com.ibm.wala.eclipse.tests/build.xml b/com.ibm.wala.eclipse.tests/build.xml new file mode 100644 index 000000000..dd8ca6643 --- /dev/null +++ b/com.ibm.wala.eclipse.tests/build.xml @@ -0,0 +1,309 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/com.ibm.wala.eclipse.tests/com.ibm.wala.eclipse.tests/.classpath b/com.ibm.wala.eclipse.tests/com.ibm.wala.eclipse.tests/.classpath new file mode 100644 index 000000000..021596729 --- /dev/null +++ b/com.ibm.wala.eclipse.tests/com.ibm.wala.eclipse.tests/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/com.ibm.wala.eclipse.tests/com.ibm.wala.eclipse.tests/.project b/com.ibm.wala.eclipse.tests/com.ibm.wala.eclipse.tests/.project new file mode 100644 index 000000000..7caeccc39 --- /dev/null +++ b/com.ibm.wala.eclipse.tests/com.ibm.wala.eclipse.tests/.project @@ -0,0 +1,28 @@ + + + com.ibm.wala.eclipse.tests + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/com.ibm.wala.eclipse.tests/com.ibm.wala.eclipse.tests/.settings/org.eclipse.jdt.core.prefs b/com.ibm.wala.eclipse.tests/com.ibm.wala.eclipse.tests/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 000000000..d3a810263 --- /dev/null +++ b/com.ibm.wala.eclipse.tests/com.ibm.wala.eclipse.tests/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,12 @@ +#Tue Oct 10 11:07:28 EDT 2006 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5 +org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve +org.eclipse.jdt.core.compiler.compliance=1.5 +org.eclipse.jdt.core.compiler.debug.lineNumber=generate +org.eclipse.jdt.core.compiler.debug.localVariable=generate +org.eclipse.jdt.core.compiler.debug.sourceFile=generate +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.source=1.5 diff --git a/com.ibm.wala.eclipse.tests/com.ibm.wala.eclipse.tests/.settings/org.eclipse.jdt.ui.prefs b/com.ibm.wala.eclipse.tests/com.ibm.wala.eclipse.tests/.settings/org.eclipse.jdt.ui.prefs new file mode 100644 index 000000000..9991bec92 --- /dev/null +++ b/com.ibm.wala.eclipse.tests/com.ibm.wala.eclipse.tests/.settings/org.eclipse.jdt.ui.prefs @@ -0,0 +1,3 @@ +#Tue Oct 10 11:07:28 EDT 2006 +eclipse.preferences.version=1 +internal.default.compliance=default diff --git a/com.ibm.wala.eclipse.tests/com.ibm.wala.eclipse.tests/META-INF/MANIFEST.MF b/com.ibm.wala.eclipse.tests/com.ibm.wala.eclipse.tests/META-INF/MANIFEST.MF new file mode 100644 index 000000000..3cb99fd5d --- /dev/null +++ b/com.ibm.wala.eclipse.tests/com.ibm.wala.eclipse.tests/META-INF/MANIFEST.MF @@ -0,0 +1,17 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Tests Plug-in +Bundle-SymbolicName: com.ibm.wala.eclipse.tests +Bundle-Version: 1.0.0 +Bundle-Activator: com.ibm.wala.eclipse.tests.Activator +Bundle-Vendor: IBM +Bundle-Localization: plugin +Require-Bundle: org.eclipse.ui, + org.eclipse.core.runtime, + org.eclipse.core.resources, + org.eclipse.jdt.core, + org.eclipse.ui.ide, + org.junit, + com.ibm.wala.core, + com.ibm.wala.eclipse +Eclipse-LazyStart: true diff --git a/com.ibm.wala.eclipse.tests/com.ibm.wala.eclipse.tests/build.properties b/com.ibm.wala.eclipse.tests/com.ibm.wala.eclipse.tests/build.properties new file mode 100644 index 000000000..41eb6ade2 --- /dev/null +++ b/com.ibm.wala.eclipse.tests/com.ibm.wala.eclipse.tests/build.properties @@ -0,0 +1,4 @@ +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + . diff --git a/com.ibm.wala.eclipse.tests/com.ibm.wala.eclipse.tests/build.xml b/com.ibm.wala.eclipse.tests/com.ibm.wala.eclipse.tests/build.xml new file mode 100644 index 000000000..dd8ca6643 --- /dev/null +++ b/com.ibm.wala.eclipse.tests/com.ibm.wala.eclipse.tests/build.xml @@ -0,0 +1,309 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/com.ibm.wala.eclipse.tests/com.ibm.wala.eclipse.tests/javaCompiler...args b/com.ibm.wala.eclipse.tests/com.ibm.wala.eclipse.tests/javaCompiler...args new file mode 100644 index 000000000..5b5529e0e --- /dev/null +++ b/com.ibm.wala.eclipse.tests/com.ibm.wala.eclipse.tests/javaCompiler...args @@ -0,0 +1,77 @@ +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.ui_3.2.0.I20060605-1400.jar[~org/eclipse/ui/internal/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.core.runtime_3.2.0.v20060603.jar[~org/eclipse/core/internal/preferences/legacy/*;~org/eclipse/core/internal/runtime/*;+org/eclipse/core/runtime/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.osgi_3.2.0.v20060601.jar[+org/eclipse/osgi/event/*;+org/eclipse/osgi/framework/console/*;+org/eclipse/osgi/framework/eventmgr/*;+org/eclipse/osgi/framework/log/*;+org/eclipse/osgi/service/datalocation/*;+org/eclipse/osgi/service/debug/*;+org/eclipse/osgi/service/environment/*;+org/eclipse/osgi/service/localization/*;+org/eclipse/osgi/service/pluginconversion/*;+org/eclipse/osgi/service/resolver/*;+org/eclipse/osgi/service/runnable/*;+org/eclipse/osgi/service/urlconversion/*;+org/eclipse/osgi/storagemanager/*;+org/eclipse/osgi/util/*;+org/osgi/framework/*;+org/osgi/service/condpermadmin/*;+org/osgi/service/packageadmin/*;+org/osgi/service/permissionadmin/*;+org/osgi/service/startlevel/*;+org/osgi/service/url/*;+org/osgi/util/tracker/*;~org/eclipse/core/runtime/adaptor/*;~org/eclipse/core/runtime/internal/adaptor/*;~org/eclipse/core/runtime/internal/stats/*;~org/eclipse/osgi/baseadaptor/*;~org/eclipse/osgi/baseadaptor/bundlefile/*;~org/eclipse/osgi/baseadaptor/hooks/*;~org/eclipse/osgi/baseadaptor/loader/*;~org/eclipse/osgi/framework/adaptor/*;~org/eclipse/osgi/framework/debug/*;~org/eclipse/osgi/framework/internal/core/*;~org/eclipse/osgi/framework/internal/protocol/*;~org/eclipse/osgi/framework/internal/protocol/bundleentry/*;~org/eclipse/osgi/framework/internal/protocol/bundleresource/*;~org/eclipse/osgi/framework/internal/protocol/reference/*;~org/eclipse/osgi/framework/internal/reliablefile/*;~org/eclipse/osgi/framework/launcher/*;~org/eclipse/osgi/framework/util/*;~org/eclipse/osgi/internal/baseadaptor/*;~org/eclipse/osgi/internal/module/*;~org/eclipse/osgi/internal/profile/*;~org/eclipse/osgi/internal/resolver/*;~org/eclipse/osgi/internal/verifier/*;~org/eclipse/osgi/internal/provisional/verifier/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.equinox.common_3.2.0.v20060603.jar[~org/eclipse/core/internal/runtime/*;~org/eclipse/core/internal/boot/*;+org/eclipse/core/runtime/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.core.jobs_3.2.0.v20060603.jar[~org/eclipse/core/internal/jobs/*;+org/eclipse/core/runtime/jobs/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.core.runtime.compatibility.registry_3.2.0.v20060603/runtime_registry_compatibility.jar[~org/eclipse/core/internal/registry/*;~org/eclipse/core/internal/registry/osgi/*;~org/eclipse/core/internal/registry/spi/*;+org/eclipse/core/runtime/*;+org/eclipse/core/runtime/dynamichelpers/*;+org/eclipse/core/runtime/spi/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.core.runtime.compatibility.registry_3.2.0.v20060603[~org/eclipse/core/internal/registry/*;~org/eclipse/core/internal/registry/osgi/*;~org/eclipse/core/internal/registry/spi/*;+org/eclipse/core/runtime/*;+org/eclipse/core/runtime/dynamichelpers/*;+org/eclipse/core/runtime/spi/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.equinox.registry_3.2.0.v20060601.jar[~org/eclipse/core/internal/registry/*;~org/eclipse/core/internal/registry/osgi/*;~org/eclipse/core/internal/registry/spi/*;+org/eclipse/core/runtime/*;+org/eclipse/core/runtime/dynamichelpers/*;+org/eclipse/core/runtime/spi/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.apache.xerces_2.8.0.v200606131651/resolver.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.apache.xerces_2.8.0.v200606131651/xercesImpl.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.apache.xerces_2.8.0.v200606131651/xml-apis.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.equinox.preferences_3.2.0.v20060601.jar[~org/eclipse/core/internal/preferences/*;~org/eclipse/core/internal/preferences/exchange/*;+org/eclipse/core/runtime/preferences/*;+org/osgi/service/prefs/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.core.runtime.compatibility.registry_3.2.0.v20060603/@dot[~org/eclipse/core/internal/registry/*;~org/eclipse/core/internal/registry/osgi/*;~org/eclipse/core/internal/registry/spi/*;+org/eclipse/core/runtime/*;+org/eclipse/core/runtime/dynamichelpers/*;+org/eclipse/core/runtime/spi/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.core.contenttype_3.2.0.v20060603.jar[~org/eclipse/core/internal/content/*;+org/eclipse/core/runtime/content/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.core.runtime.compatibility.auth_3.2.0.v20060601.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.swt_3.2.0.v3232o.jar[+org/eclipse/swt/*;+org/eclipse/swt/accessibility/*;+org/eclipse/swt/awt/*;+org/eclipse/swt/browser/*;+org/eclipse/swt/custom/*;+org/eclipse/swt/dnd/*;+org/eclipse/swt/events/*;+org/eclipse/swt/graphics/*;+org/eclipse/swt/layout/*;+org/eclipse/swt/opengl/*;+org/eclipse/swt/printing/*;+org/eclipse/swt/program/*;+org/eclipse/swt/widgets/*;~org/eclipse/swt/internal/*;~org/eclipse/swt/internal/image/*;~org/eclipse/swt/internal/theme/*;+org/eclipse/swt/ole/win32/*;~org/eclipse/swt/internal/gdip/*;~org/eclipse/swt/internal/ole/win32/*;~org/eclipse/swt/internal/win32/*;~org/eclipse/swt/internal/opengl/win32/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.swt.win32.win32.x86_3.2.0.v3232m.jar[+org/eclipse/swt/*;+org/eclipse/swt/accessibility/*;+org/eclipse/swt/awt/*;+org/eclipse/swt/browser/*;+org/eclipse/swt/custom/*;+org/eclipse/swt/dnd/*;+org/eclipse/swt/events/*;+org/eclipse/swt/graphics/*;+org/eclipse/swt/layout/*;+org/eclipse/swt/opengl/*;+org/eclipse/swt/printing/*;+org/eclipse/swt/program/*;+org/eclipse/swt/widgets/*;~org/eclipse/swt/internal/*;~org/eclipse/swt/internal/image/*;~org/eclipse/swt/internal/theme/*;+org/eclipse/swt/ole/win32/*;~org/eclipse/swt/internal/gdip/*;~org/eclipse/swt/internal/ole/win32/*;~org/eclipse/swt/internal/win32/*;~org/eclipse/swt/internal/opengl/win32/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.jface_3.2.0.I20060605-1400.jar[+org/eclipse/jface/*;+org/eclipse/jface/action/*;+org/eclipse/jface/action/images/*;+org/eclipse/jface/bindings/*;+org/eclipse/jface/bindings/keys/*;+org/eclipse/jface/bindings/keys/formatting/*;+org/eclipse/jface/commands/*;+org/eclipse/jface/contexts/*;+org/eclipse/jface/dialogs/*;+org/eclipse/jface/dialogs/images/*;+org/eclipse/jface/fieldassist/*;+org/eclipse/jface/fieldassist/images/*;+org/eclipse/jface/images/*;~org/eclipse/jface/internal/provisional/action/*;+org/eclipse/jface/layout/*;+org/eclipse/jface/menus/*;+org/eclipse/jface/operation/*;+org/eclipse/jface/preference/*;+org/eclipse/jface/preference/images/*;+org/eclipse/jface/resource/*;+org/eclipse/jface/util/*;+org/eclipse/jface/viewers/*;+org/eclipse/jface/viewers/deferred/*;+org/eclipse/jface/window/*;+org/eclipse/jface/wizard/*;+org/eclipse/jface/wizard/images/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.core.commands_3.2.0.I20060605-1400.jar[+org/eclipse/core/commands/*;+org/eclipse/core/commands/common/*;+org/eclipse/core/commands/contexts/*;+org/eclipse/core/commands/operations/*;+org/eclipse/core/commands/util/*;~org/eclipse/core/internal/commands/operations/*;~org/eclipse/core/internal/commands/util/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.ui.workbench_3.2.0.I20060605-1400.jar[+org/eclipse/ui/*;+org/eclipse/ui/about/*;+org/eclipse/ui/actions/*;+org/eclipse/ui/activities/*;+org/eclipse/ui/application/*;+org/eclipse/ui/branding/*;+org/eclipse/ui/browser/*;+org/eclipse/ui/commands/*;+org/eclipse/ui/contexts/*;+org/eclipse/ui/dialogs/*;+org/eclipse/ui/fieldassist/*;+org/eclipse/ui/handlers/*;+org/eclipse/ui/help/*;~org/eclipse/ui/internal/*;~org/eclipse/ui/internal/about/*;~org/eclipse/ui/internal/actions/*;~org/eclipse/ui/internal/activities/*;~org/eclipse/ui/internal/activities/ws/*;~org/eclipse/ui/internal/application/*;~org/eclipse/ui/internal/browser/*;~org/eclipse/ui/internal/commands/*;~org/eclipse/ui/internal/contexts/*;~org/eclipse/ui/internal/decorators/*;~org/eclipse/ui/internal/dialogs/*;~org/eclipse/ui/internal/dnd/*;~org/eclipse/ui/internal/editorsupport/*;~org/eclipse/ui/internal/expressions/*;~org/eclipse/ui/internal/handlers/*;~org/eclipse/ui/internal/help/*;~org/eclipse/ui/internal/intro/*;~org/eclipse/ui/internal/keys/*;~org/eclipse/ui/internal/layout/*;~org/eclipse/ui/internal/menus/*;~org/eclipse/ui/internal/misc/*;~org/eclipse/ui/internal/operations/*;~org/eclipse/ui/internal/part/*;~org/eclipse/ui/internal/preferences/*;~org/eclipse/ui/internal/presentations/*;~org/eclipse/ui/internal/presentations/defaultpresentation/*;~org/eclipse/ui/internal/presentations/util/*;~org/eclipse/ui/internal/progress/*;~org/eclipse/ui/internal/provisional/application/*;~org/eclipse/ui/internal/provisional/presentations/*;~org/eclipse/ui/internal/registry/*;~org/eclipse/ui/internal/services/*;~org/eclipse/ui/internal/testing/*;~org/eclipse/ui/internal/themes/*;~org/eclipse/ui/internal/util/*;~org/eclipse/ui/internal/wizards/*;~org/eclipse/ui/internal/wizards/preferences/*;+org/eclipse/ui/intro/*;+org/eclipse/ui/keys/*;+org/eclipse/ui/menus/*;+org/eclipse/ui/model/*;+org/eclipse/ui/operations/*;+org/eclipse/ui/part/*;+org/eclipse/ui/plugin/*;+org/eclipse/ui/preferences/*;+org/eclipse/ui/presentations/*;+org/eclipse/ui/progress/*;+org/eclipse/ui/services/*;+org/eclipse/ui/testing/*;+org/eclipse/ui/themes/*;+org/eclipse/ui/views/*;+org/eclipse/ui/wizards/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.ui.workbench.compatibility_3.2.0.I20060605-1400/@dot[+org/eclipse/ui/*;+org/eclipse/ui/about/*;+org/eclipse/ui/actions/*;+org/eclipse/ui/activities/*;+org/eclipse/ui/application/*;+org/eclipse/ui/branding/*;+org/eclipse/ui/browser/*;+org/eclipse/ui/commands/*;+org/eclipse/ui/contexts/*;+org/eclipse/ui/dialogs/*;+org/eclipse/ui/fieldassist/*;+org/eclipse/ui/handlers/*;+org/eclipse/ui/help/*;~org/eclipse/ui/internal/*;~org/eclipse/ui/internal/about/*;~org/eclipse/ui/internal/actions/*;~org/eclipse/ui/internal/activities/*;~org/eclipse/ui/internal/activities/ws/*;~org/eclipse/ui/internal/application/*;~org/eclipse/ui/internal/browser/*;~org/eclipse/ui/internal/commands/*;~org/eclipse/ui/internal/contexts/*;~org/eclipse/ui/internal/decorators/*;~org/eclipse/ui/internal/dialogs/*;~org/eclipse/ui/internal/dnd/*;~org/eclipse/ui/internal/editorsupport/*;~org/eclipse/ui/internal/expressions/*;~org/eclipse/ui/internal/handlers/*;~org/eclipse/ui/internal/help/*;~org/eclipse/ui/internal/intro/*;~org/eclipse/ui/internal/keys/*;~org/eclipse/ui/internal/layout/*;~org/eclipse/ui/internal/menus/*;~org/eclipse/ui/internal/misc/*;~org/eclipse/ui/internal/operations/*;~org/eclipse/ui/internal/part/*;~org/eclipse/ui/internal/preferences/*;~org/eclipse/ui/internal/presentations/*;~org/eclipse/ui/internal/presentations/defaultpresentation/*;~org/eclipse/ui/internal/presentations/util/*;~org/eclipse/ui/internal/progress/*;~org/eclipse/ui/internal/provisional/application/*;~org/eclipse/ui/internal/provisional/presentations/*;~org/eclipse/ui/internal/registry/*;~org/eclipse/ui/internal/services/*;~org/eclipse/ui/internal/testing/*;~org/eclipse/ui/internal/themes/*;~org/eclipse/ui/internal/util/*;~org/eclipse/ui/internal/wizards/*;~org/eclipse/ui/internal/wizards/preferences/*;+org/eclipse/ui/intro/*;+org/eclipse/ui/keys/*;+org/eclipse/ui/menus/*;+org/eclipse/ui/model/*;+org/eclipse/ui/operations/*;+org/eclipse/ui/part/*;+org/eclipse/ui/plugin/*;+org/eclipse/ui/preferences/*;+org/eclipse/ui/presentations/*;+org/eclipse/ui/progress/*;+org/eclipse/ui/services/*;+org/eclipse/ui/testing/*;+org/eclipse/ui/themes/*;+org/eclipse/ui/views/*;+org/eclipse/ui/wizards/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.ui.workbench.compatibility_3.2.0.I20060605-1400/compatibility.jar[+org/eclipse/ui/*;+org/eclipse/ui/about/*;+org/eclipse/ui/actions/*;+org/eclipse/ui/activities/*;+org/eclipse/ui/application/*;+org/eclipse/ui/branding/*;+org/eclipse/ui/browser/*;+org/eclipse/ui/commands/*;+org/eclipse/ui/contexts/*;+org/eclipse/ui/dialogs/*;+org/eclipse/ui/fieldassist/*;+org/eclipse/ui/handlers/*;+org/eclipse/ui/help/*;~org/eclipse/ui/internal/*;~org/eclipse/ui/internal/about/*;~org/eclipse/ui/internal/actions/*;~org/eclipse/ui/internal/activities/*;~org/eclipse/ui/internal/activities/ws/*;~org/eclipse/ui/internal/application/*;~org/eclipse/ui/internal/browser/*;~org/eclipse/ui/internal/commands/*;~org/eclipse/ui/internal/contexts/*;~org/eclipse/ui/internal/decorators/*;~org/eclipse/ui/internal/dialogs/*;~org/eclipse/ui/internal/dnd/*;~org/eclipse/ui/internal/editorsupport/*;~org/eclipse/ui/internal/expressions/*;~org/eclipse/ui/internal/handlers/*;~org/eclipse/ui/internal/help/*;~org/eclipse/ui/internal/intro/*;~org/eclipse/ui/internal/keys/*;~org/eclipse/ui/internal/layout/*;~org/eclipse/ui/internal/menus/*;~org/eclipse/ui/internal/misc/*;~org/eclipse/ui/internal/operations/*;~org/eclipse/ui/internal/part/*;~org/eclipse/ui/internal/preferences/*;~org/eclipse/ui/internal/presentations/*;~org/eclipse/ui/internal/presentations/defaultpresentation/*;~org/eclipse/ui/internal/presentations/util/*;~org/eclipse/ui/internal/progress/*;~org/eclipse/ui/internal/provisional/application/*;~org/eclipse/ui/internal/provisional/presentations/*;~org/eclipse/ui/internal/registry/*;~org/eclipse/ui/internal/services/*;~org/eclipse/ui/internal/testing/*;~org/eclipse/ui/internal/themes/*;~org/eclipse/ui/internal/util/*;~org/eclipse/ui/internal/wizards/*;~org/eclipse/ui/internal/wizards/preferences/*;+org/eclipse/ui/intro/*;+org/eclipse/ui/keys/*;+org/eclipse/ui/menus/*;+org/eclipse/ui/model/*;+org/eclipse/ui/operations/*;+org/eclipse/ui/part/*;+org/eclipse/ui/plugin/*;+org/eclipse/ui/preferences/*;+org/eclipse/ui/presentations/*;+org/eclipse/ui/progress/*;+org/eclipse/ui/services/*;+org/eclipse/ui/testing/*;+org/eclipse/ui/themes/*;+org/eclipse/ui/views/*;+org/eclipse/ui/wizards/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/com.ibm.icu_3.4.4.1.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.help_3.2.0.v20060602.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.core.expressions_3.2.0.v20060605-1400.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.core.resources_3.2.0.v20060603.jar[~org/eclipse/core/internal/dtree/*;~org/eclipse/core/internal/events/*;~org/eclipse/core/internal/localstore/*;~org/eclipse/core/internal/properties/*;~org/eclipse/core/internal/propertytester/*;~org/eclipse/core/internal/refresh/*;~org/eclipse/core/internal/resources/*;~org/eclipse/core/internal/resources/mapping/*;~org/eclipse/core/internal/utils/*;~org/eclipse/core/internal/watson/*;+org/eclipse/core/resources/*;+org/eclipse/core/resources/mapping/*;+org/eclipse/core/resources/refresh/*;+org/eclipse/core/resources/team/*;~org/eclipse/core/internal/indexing/*;~org/eclipse/core/internal/resources/refresh/win32/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.core.resources.compatibility_3.2.0.v20060603.jar[~org/eclipse/core/internal/dtree/*;~org/eclipse/core/internal/events/*;~org/eclipse/core/internal/localstore/*;~org/eclipse/core/internal/properties/*;~org/eclipse/core/internal/propertytester/*;~org/eclipse/core/internal/refresh/*;~org/eclipse/core/internal/resources/*;~org/eclipse/core/internal/resources/mapping/*;~org/eclipse/core/internal/utils/*;~org/eclipse/core/internal/watson/*;+org/eclipse/core/resources/*;+org/eclipse/core/resources/mapping/*;+org/eclipse/core/resources/refresh/*;+org/eclipse/core/resources/team/*;~org/eclipse/core/internal/indexing/*;~org/eclipse/core/internal/resources/refresh/win32/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.core.resources.win32_3.2.0.v20060603.jar[~org/eclipse/core/internal/dtree/*;~org/eclipse/core/internal/events/*;~org/eclipse/core/internal/localstore/*;~org/eclipse/core/internal/properties/*;~org/eclipse/core/internal/propertytester/*;~org/eclipse/core/internal/refresh/*;~org/eclipse/core/internal/resources/*;~org/eclipse/core/internal/resources/mapping/*;~org/eclipse/core/internal/utils/*;~org/eclipse/core/internal/watson/*;+org/eclipse/core/resources/*;+org/eclipse/core/resources/mapping/*;+org/eclipse/core/resources/refresh/*;+org/eclipse/core/resources/team/*;~org/eclipse/core/internal/indexing/*;~org/eclipse/core/internal/resources/refresh/win32/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.core.runtime.compatibility_3.1.100.v20060603.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.update.configurator_3.2.0.v20060605.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.ant.core_3.1.100.v20060531.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.core.variables_3.1.100.v20060605.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.core.filesystem_1.0.0.v20060603.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.core.filesystem.win32.x86_1.0.0.v20060603.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.jdt.core_3.2.0.v_671.jar[+org/eclipse/jdt/core/*;+org/eclipse/jdt/core/compiler/*;+org/eclipse/jdt/core/dom/*;+org/eclipse/jdt/core/dom/rewrite/*;+org/eclipse/jdt/core/eval/*;+org/eclipse/jdt/core/formatter/*;+org/eclipse/jdt/core/jdom/*;+org/eclipse/jdt/core/search/*;+org/eclipse/jdt/core/util/*;~org/eclipse/jdt/internal/codeassist/*;~org/eclipse/jdt/internal/codeassist/complete/*;~org/eclipse/jdt/internal/codeassist/impl/*;~org/eclipse/jdt/internal/codeassist/select/*;~org/eclipse/jdt/internal/compiler/*;~org/eclipse/jdt/internal/compiler/ast/*;~org/eclipse/jdt/internal/compiler/batch/*;~org/eclipse/jdt/internal/compiler/classfmt/*;~org/eclipse/jdt/internal/compiler/codegen/*;~org/eclipse/jdt/internal/compiler/env/*;~org/eclipse/jdt/internal/compiler/flow/*;~org/eclipse/jdt/internal/compiler/impl/*;~org/eclipse/jdt/internal/compiler/lookup/*;~org/eclipse/jdt/internal/compiler/parser/*;~org/eclipse/jdt/internal/compiler/parser/diagnose/*;~org/eclipse/jdt/internal/compiler/problem/*;~org/eclipse/jdt/internal/compiler/util/*;~org/eclipse/jdt/internal/core/*;~org/eclipse/jdt/internal/core/builder/*;~org/eclipse/jdt/internal/core/dom/rewrite/*;~org/eclipse/jdt/internal/core/eval/*;~org/eclipse/jdt/internal/core/hierarchy/*;~org/eclipse/jdt/internal/core/index/*;~org/eclipse/jdt/internal/core/jdom/*;~org/eclipse/jdt/internal/core/search/*;~org/eclipse/jdt/internal/core/search/indexing/*;~org/eclipse/jdt/internal/core/search/matching/*;~org/eclipse/jdt/internal/core/search/processing/*;~org/eclipse/jdt/internal/core/util/*;~org/eclipse/jdt/internal/eval/*;~org/eclipse/jdt/internal/formatter/*;~org/eclipse/jdt/internal/formatter/align/*;~org/eclipse/jdt/internal/formatter/comment/*;~org/eclipse/jdt/internal/formatter/old/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.text_3.2.0.v20060605-1400.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.team.core_3.2.0.I200606051140.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.ui.ide_3.2.0.I20060605-1400.jar[+org/eclipse/ui/*;+org/eclipse/ui/actions/*;+org/eclipse/ui/dialogs/*;+org/eclipse/ui/ide/*;+org/eclipse/ui/ide/dialogs/*;+org/eclipse/ui/ide/fileSystem/*;~org/eclipse/ui/internal/ide/*;~org/eclipse/ui/internal/ide/actions/*;~org/eclipse/ui/internal/ide/commands/*;~org/eclipse/ui/internal/ide/dialogs/*;~org/eclipse/ui/internal/ide/filesystem/*;~org/eclipse/ui/internal/ide/handlers/*;~org/eclipse/ui/internal/ide/misc/*;~org/eclipse/ui/internal/ide/model/*;~org/eclipse/ui/internal/ide/registry/*;~org/eclipse/ui/internal/ide/update/*;~org/eclipse/ui/internal/views/bookmarkexplorer/*;~org/eclipse/ui/internal/views/framelist/*;~org/eclipse/ui/internal/views/navigator/*;~org/eclipse/ui/internal/views/properties/*;~org/eclipse/ui/internal/views/tasklist/*;~org/eclipse/ui/internal/wizards/datatransfer/*;~org/eclipse/ui/internal/wizards/newresource/*;+org/eclipse/ui/model/*;+org/eclipse/ui/part/*;+org/eclipse/ui/views/bookmarkexplorer/*;+org/eclipse/ui/views/framelist/*;+org/eclipse/ui/views/markers/*;~org/eclipse/ui/views/markers/internal/*;+org/eclipse/ui/views/navigator/*;+org/eclipse/ui/views/properties/*;+org/eclipse/ui/views/tasklist/*;+org/eclipse/ui/wizards/datatransfer/*;+org/eclipse/ui/wizards/newresource/*;~org/eclipse/ui/internal/editorsupport/win32/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.ui.win32_3.2.0.I20060605-1400.jar[+org/eclipse/ui/*;+org/eclipse/ui/actions/*;+org/eclipse/ui/dialogs/*;+org/eclipse/ui/ide/*;+org/eclipse/ui/ide/dialogs/*;+org/eclipse/ui/ide/fileSystem/*;~org/eclipse/ui/internal/ide/*;~org/eclipse/ui/internal/ide/actions/*;~org/eclipse/ui/internal/ide/commands/*;~org/eclipse/ui/internal/ide/dialogs/*;~org/eclipse/ui/internal/ide/filesystem/*;~org/eclipse/ui/internal/ide/handlers/*;~org/eclipse/ui/internal/ide/misc/*;~org/eclipse/ui/internal/ide/model/*;~org/eclipse/ui/internal/ide/registry/*;~org/eclipse/ui/internal/ide/update/*;~org/eclipse/ui/internal/views/bookmarkexplorer/*;~org/eclipse/ui/internal/views/framelist/*;~org/eclipse/ui/internal/views/navigator/*;~org/eclipse/ui/internal/views/properties/*;~org/eclipse/ui/internal/views/tasklist/*;~org/eclipse/ui/internal/wizards/datatransfer/*;~org/eclipse/ui/internal/wizards/newresource/*;+org/eclipse/ui/model/*;+org/eclipse/ui/part/*;+org/eclipse/ui/views/bookmarkexplorer/*;+org/eclipse/ui/views/framelist/*;+org/eclipse/ui/views/markers/*;~org/eclipse/ui/views/markers/internal/*;+org/eclipse/ui/views/navigator/*;+org/eclipse/ui/views/properties/*;+org/eclipse/ui/views/tasklist/*;+org/eclipse/ui/wizards/datatransfer/*;+org/eclipse/ui/wizards/newresource/*;~org/eclipse/ui/internal/editorsupport/win32/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.ui.views_3.2.0.I20060605-1400.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.update.core_3.2.0.v20060605.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.update.core.win32_3.2.0.v20060605.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.update.ui_3.2.0.v20060605.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.ui.forms_3.2.0.v20060602.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.junit_3.8.1/junit.jar[+junit/awtui/*;+junit/extensions/*;+junit/framework/*;+junit/runner/*;+junit/swingui/*;+junit/swingui/icons/*;+junit/textui/*;?**/*] +#ADAPTER#ACCESS#com.ibm.wala.core/bin/[+com/ibm/wala/analysis/pointers/*;+com/ibm/wala/analysis/reflection/*;+com/ibm/wala/analysis/stackMachine/*;+com/ibm/wala/analysis/typeInference/*;+com/ibm/wala/cfg/*;+com/ibm/wala/cfg/cdg/*;+com/ibm/wala/classLoader/*;+com/ibm/wala/client/*;+com/ibm/wala/client/impl/*;+com/ibm/wala/core/plugin/*;+com/ibm/wala/dataflow/IFDS/*;+com/ibm/wala/dataflow/graph/*;+com/ibm/wala/dataflow/ssa/*;+com/ibm/wala/dynamic/*;+com/ibm/wala/emf/wrappers/*;+com/ibm/wala/escape/*;+com/ibm/wala/fixedpoint/impl/*;+com/ibm/wala/fixpoint/*;+com/ibm/wala/ipa/callgraph/*;+com/ibm/wala/ipa/callgraph/impl/*;+com/ibm/wala/ipa/callgraph/propagation/*;+com/ibm/wala/ipa/callgraph/propagation/cfa/*;+com/ibm/wala/ipa/callgraph/propagation/rta/*;+com/ibm/wala/ipa/cfg/*;+com/ibm/wala/ipa/cha/*;+com/ibm/wala/ipa/summaries/*;+com/ibm/wala/model/*;+com/ibm/wala/model/java/lang/*;+com/ibm/wala/properties/*;+com/ibm/wala/ssa/*;+com/ibm/wala/ssa/analysis/*;+com/ibm/wala/types/*;+com/ibm/wala/util/*;+com/ibm/wala/util/bytecode/*;+com/ibm/wala/util/collections/*;+com/ibm/wala/util/config/*;+com/ibm/wala/util/debug/*;+com/ibm/wala/util/graph/*;+com/ibm/wala/util/graph/impl/*;+com/ibm/wala/util/graph/traverse/*;+com/ibm/wala/util/heapTrace/*;+com/ibm/wala/util/intertionalization/*;+com/ibm/wala/util/intset/*;+com/ibm/wala/util/io/*;+com/ibm/wala/util/logging/*;+com/ibm/wala/util/math/*;+com/ibm/wala/util/perf/*;+com/ibm/wala/util/system/*;+com/ibm/wala/util/warnings/*;+com/ibm/wala/viz/*;?**/*] +#ADAPTER#ACCESS#com.ibm.wala.core/@dot[+com/ibm/wala/analysis/pointers/*;+com/ibm/wala/analysis/reflection/*;+com/ibm/wala/analysis/stackMachine/*;+com/ibm/wala/analysis/typeInference/*;+com/ibm/wala/cfg/*;+com/ibm/wala/cfg/cdg/*;+com/ibm/wala/classLoader/*;+com/ibm/wala/client/*;+com/ibm/wala/client/impl/*;+com/ibm/wala/core/plugin/*;+com/ibm/wala/dataflow/IFDS/*;+com/ibm/wala/dataflow/graph/*;+com/ibm/wala/dataflow/ssa/*;+com/ibm/wala/dynamic/*;+com/ibm/wala/emf/wrappers/*;+com/ibm/wala/escape/*;+com/ibm/wala/fixedpoint/impl/*;+com/ibm/wala/fixpoint/*;+com/ibm/wala/ipa/callgraph/*;+com/ibm/wala/ipa/callgraph/impl/*;+com/ibm/wala/ipa/callgraph/propagation/*;+com/ibm/wala/ipa/callgraph/propagation/cfa/*;+com/ibm/wala/ipa/callgraph/propagation/rta/*;+com/ibm/wala/ipa/cfg/*;+com/ibm/wala/ipa/cha/*;+com/ibm/wala/ipa/summaries/*;+com/ibm/wala/model/*;+com/ibm/wala/model/java/lang/*;+com/ibm/wala/properties/*;+com/ibm/wala/ssa/*;+com/ibm/wala/ssa/analysis/*;+com/ibm/wala/types/*;+com/ibm/wala/util/*;+com/ibm/wala/util/bytecode/*;+com/ibm/wala/util/collections/*;+com/ibm/wala/util/config/*;+com/ibm/wala/util/debug/*;+com/ibm/wala/util/graph/*;+com/ibm/wala/util/graph/impl/*;+com/ibm/wala/util/graph/traverse/*;+com/ibm/wala/util/heapTrace/*;+com/ibm/wala/util/intertionalization/*;+com/ibm/wala/util/intset/*;+com/ibm/wala/util/io/*;+com/ibm/wala/util/logging/*;+com/ibm/wala/util/math/*;+com/ibm/wala/util/perf/*;+com/ibm/wala/util/system/*;+com/ibm/wala/util/warnings/*;+com/ibm/wala/viz/*;?**/*] +#ADAPTER#ACCESS#com.ibm.wala.emf/bin/[+com/ibm/wala/ecore/common/*;+com/ibm/wala/ecore/common/impl/*;+com/ibm/wala/ecore/common/util/*;+com/ibm/wala/ecore/graph/*;+com/ibm/wala/ecore/graph/impl/*;+com/ibm/wala/ecore/graph/util/*;+com/ibm/wala/ecore/j2ee/scope/*;+com/ibm/wala/ecore/j2ee/scope/impl/*;+com/ibm/wala/ecore/j2ee/scope/util/*;+com/ibm/wala/ecore/java/*;+com/ibm/wala/ecore/java/callGraph/*;+com/ibm/wala/ecore/java/callGraph/impl/*;+com/ibm/wala/ecore/java/callGraph/util/*;+com/ibm/wala/ecore/java/impl/*;+com/ibm/wala/ecore/java/pointerAnalysis/*;+com/ibm/wala/ecore/java/pointerAnalysis/impl/*;+com/ibm/wala/ecore/java/pointerAnalysis/util/*;+com/ibm/wala/ecore/java/scope/*;+com/ibm/wala/ecore/java/scope/impl/*;+com/ibm/wala/ecore/java/scope/util/*;+com/ibm/wala/ecore/java/util/*;+com/ibm/wala/ecore/perf/*;+com/ibm/wala/ecore/perf/impl/*;+com/ibm/wala/ecore/perf/util/*;+com/ibm/wala/ecore/regex/*;+com/ibm/wala/ecore/regex/impl/*;+com/ibm/wala/ecore/regex/util/*;?**/*] +#ADAPTER#ACCESS#com.ibm.wala.emf/@dot[+com/ibm/wala/ecore/common/*;+com/ibm/wala/ecore/common/impl/*;+com/ibm/wala/ecore/common/util/*;+com/ibm/wala/ecore/graph/*;+com/ibm/wala/ecore/graph/impl/*;+com/ibm/wala/ecore/graph/util/*;+com/ibm/wala/ecore/j2ee/scope/*;+com/ibm/wala/ecore/j2ee/scope/impl/*;+com/ibm/wala/ecore/j2ee/scope/util/*;+com/ibm/wala/ecore/java/*;+com/ibm/wala/ecore/java/callGraph/*;+com/ibm/wala/ecore/java/callGraph/impl/*;+com/ibm/wala/ecore/java/callGraph/util/*;+com/ibm/wala/ecore/java/impl/*;+com/ibm/wala/ecore/java/pointerAnalysis/*;+com/ibm/wala/ecore/java/pointerAnalysis/impl/*;+com/ibm/wala/ecore/java/pointerAnalysis/util/*;+com/ibm/wala/ecore/java/scope/*;+com/ibm/wala/ecore/java/scope/impl/*;+com/ibm/wala/ecore/java/scope/util/*;+com/ibm/wala/ecore/java/util/*;+com/ibm/wala/ecore/perf/*;+com/ibm/wala/ecore/perf/impl/*;+com/ibm/wala/ecore/perf/util/*;+com/ibm/wala/ecore/regex/*;+com/ibm/wala/ecore/regex/impl/*;+com/ibm/wala/ecore/regex/util/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.emf.ecore_2.2.0.v200606271057.jar[+org/eclipse/emf/ecore/*;+org/eclipse/emf/ecore/impl/*;+org/eclipse/emf/ecore/plugin/*;+org/eclipse/emf/ecore/resource/*;+org/eclipse/emf/ecore/resource/impl/*;+org/eclipse/emf/ecore/util/*;+org/eclipse/emf/ecore/xml/namespace/*;+org/eclipse/emf/ecore/xml/namespace/impl/*;+org/eclipse/emf/ecore/xml/namespace/util/*;+org/eclipse/emf/ecore/xml/type/*;+org/eclipse/emf/ecore/xml/type/impl/*;+org/eclipse/emf/ecore/xml/type/internal/*;+org/eclipse/emf/ecore/xml/type/util/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.emf.common_2.2.0.v200606271057.jar[+org/eclipse/emf/common/*;+org/eclipse/emf/common/archive/*;+org/eclipse/emf/common/command/*;+org/eclipse/emf/common/notify/*;+org/eclipse/emf/common/notify/impl/*;+org/eclipse/emf/common/util/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.emf.ecore.xmi_2.2.0.v200606271057.jar[+org/eclipse/emf/ecore/xmi/*;+org/eclipse/emf/ecore/xmi/impl/*;+org/eclipse/emf/ecore/xmi/util/*;?**/*] +#ADAPTER#ACCESS#com.ibm.wala.shrike/bin/[+com/ibm/wala/shrike/bench/*;+com/ibm/wala/shrike/copywriter/*;+com/ibm/wala/shrike/tools/*;+com/ibm/wala/shrikeBT/*;+com/ibm/wala/shrikeBT/analysis/*;+com/ibm/wala/shrikeBT/info/*;+com/ibm/wala/shrikeBT/shrikeCT/*;+com/ibm/wala/shrikeBT/shrikeCT/tools/*;+com/ibm/wala/shrikeBT/tools/*;+com/ibm/wala/shrikeCT/*;?**/*] +#ADAPTER#ACCESS#com.ibm.wala.shrike/@dot[+com/ibm/wala/shrike/bench/*;+com/ibm/wala/shrike/copywriter/*;+com/ibm/wala/shrike/tools/*;+com/ibm/wala/shrikeBT/*;+com/ibm/wala/shrikeBT/analysis/*;+com/ibm/wala/shrikeBT/info/*;+com/ibm/wala/shrikeBT/shrikeCT/*;+com/ibm/wala/shrikeBT/shrikeCT/tools/*;+com/ibm/wala/shrikeBT/tools/*;+com/ibm/wala/shrikeCT/*;?**/*] +#ADAPTER#ACCESS#com.ibm.wala.eclipse/bin/[+com/ibm/wala/eclipse/util/*;+com/ibm/wala/eclipse/views/cfg/*;?**/*] +#ADAPTER#ACCESS#com.ibm.wala.eclipse/@dot[+com/ibm/wala/eclipse/util/*;+com/ibm/wala/eclipse/views/cfg/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.jdt.ui_3.2.0.v20060605-1400.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.ui.console_3.1.100.v20060605.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.jface.text_3.2.0.v20060605-1400.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.ui.workbench.texteditor_3.2.0.v20060605-1400.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.search_3.2.0.v20060605-1400.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.core.filebuffers_3.2.0.v20060605-1400.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.debug.core_3.2.0.v20060605.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.debug.ui_3.2.0.v20060605.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.ui.editors_3.2.0.v20060605-1400.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.jdt.launching_3.2.0.v20060605.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.jdt.debug_3.2.0.v20060605/jdi.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.jdt.debug_3.2.0.v20060605/jdimodel.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.jdt.debug_3.2.0.v20060605/tools.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.compare_3.2.0.v20060605.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.team.ui_3.2.0.I200606051140.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.ui.navigator_3.2.0.I20060605-1400.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.ui.navigator.resources_3.2.0.I20060605-1400.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.ui.views.properties.tabbed_3.2.0.I20060605-1400.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.ltk.core.refactoring_3.2.0.v20060605-1400.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.ltk.ui.refactoring_3.2.0.v20060605-1400.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.jdt.core.manipulation_1.0.0.v20060605-1400.jar[?**/*] diff --git a/com.ibm.wala.eclipse.tests/com.ibm.wala.eclipse.tests/launchers/wala.eclipse.tests.launch b/com.ibm.wala.eclipse.tests/com.ibm.wala.eclipse.tests/launchers/wala.eclipse.tests.launch new file mode 100644 index 000000000..c3b6fa6f0 --- /dev/null +++ b/com.ibm.wala.eclipse.tests/com.ibm.wala.eclipse.tests/launchers/wala.eclipse.tests.launch @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/com.ibm.wala.eclipse.tests/com.ibm.wala.eclipse.tests/src/com/ibm/wala/eclipse/tests/Activator.java b/com.ibm.wala.eclipse.tests/com.ibm.wala.eclipse.tests/src/com/ibm/wala/eclipse/tests/Activator.java new file mode 100644 index 000000000..292e08000 --- /dev/null +++ b/com.ibm.wala.eclipse.tests/com.ibm.wala.eclipse.tests/src/com/ibm/wala/eclipse/tests/Activator.java @@ -0,0 +1,60 @@ +/******************************************************************************* + * 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.eclipse.tests; + +import org.eclipse.ui.plugin.AbstractUIPlugin; +import org.osgi.framework.BundleContext; + +/** + * The activator class controls the plug-in life cycle + */ +public class Activator extends AbstractUIPlugin { + + // The plug-in ID + public static final String PLUGIN_ID = "com.ibm.wala.eclipse.tests"; + + // The shared instance + private static Activator plugin; + + /** + * The constructor + */ + public Activator() { + plugin = this; + } + + /* + * (non-Javadoc) + * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext) + */ + public void start(BundleContext context) throws Exception { + super.start(context); + } + + /* + * (non-Javadoc) + * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext) + */ + public void stop(BundleContext context) throws Exception { + plugin = null; + super.stop(context); + } + + /** + * Returns the shared instance + * + * @return the shared instance + */ + public static Activator getDefault() { + return plugin; + } + +} diff --git a/com.ibm.wala.eclipse.tests/com.ibm.wala.eclipse.tests/src/com/ibm/wala/eclipse/tests/EclipseTestUtil.java b/com.ibm.wala.eclipse.tests/com.ibm.wala.eclipse.tests/src/com/ibm/wala/eclipse/tests/EclipseTestUtil.java new file mode 100644 index 000000000..78d8f25a2 --- /dev/null +++ b/com.ibm.wala.eclipse.tests/com.ibm.wala.eclipse.tests/src/com/ibm/wala/eclipse/tests/EclipseTestUtil.java @@ -0,0 +1,131 @@ +/******************************************************************************* + * 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.eclipse.tests; + +import java.io.File; +import java.io.IOException; +import java.lang.reflect.InvocationTargetException; +import java.net.URL; +import java.util.List; +import java.util.zip.ZipException; +import java.util.zip.ZipFile; + +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IWorkspaceRoot; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.FileLocator; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.core.runtime.Path; +import org.eclipse.core.runtime.Platform; +import org.eclipse.ui.dialogs.IOverwriteQuery; +import org.eclipse.ui.wizards.datatransfer.ImportOperation; +import org.eclipse.ui.wizards.datatransfer.ZipFileStructureProvider; +import org.osgi.framework.Bundle; + +public class EclipseTestUtil { + + public static void importZippedProject(String zipFileName) { + ZipFile zipFile = getZipFile(zipFileName); + ZipFileStructureProvider zp = new ZipFileStructureProvider(zipFile); + List children = zp.getChildren(zp.getRoot()); + Object element = children.get(0); + String projectName = zp.getLabel(element); + createOpenProject(projectName); + importZipfile(zipFile,zp); + } + + public static void createOpenProject(String projectName) { + IWorkspaceRoot root = getWorkspace(); + IProject project = root.getProject(projectName); + try { + project.create(null); + project.open(null); + } catch (CoreException e) { + e.printStackTrace(); + } + } + + protected static void importZipfile(ZipFile sourceZip, ZipFileStructureProvider provider) { + IPath containerPath = getWorkspacePath(); + + ImportOperation importOp = new ImportOperation(containerPath,provider.getRoot(), provider, + new IOverwriteQuery() { + public String queryOverwrite(String pathString) { + return IOverwriteQuery.ALL; + } + } + ); + + importOp.setCreateContainerStructure(true); + importOp.setOverwriteResources(true); + try { + importOp.run(new NullProgressMonitor()); + } catch (InvocationTargetException e) { + e.printStackTrace(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + + try { + sourceZip.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + + public static File getTestDataFile(String filename) { + Bundle bundle = Platform.getBundle(Activator.PLUGIN_ID); + IPath path = new Path("testdata").append(filename); + + URL url = FileLocator.find(bundle, path, null); + try { + URL fileURL = FileLocator.toFileURL(url); + File file = new File(fileURL.getPath()); + return file; + } catch (IOException e) { + reportException(e); + } + + return null; + } + + public static ZipFile getZipFile(String testArchive) { + File file = getTestDataFile(testArchive); + if(file != null) { + try { + return new ZipFile(file); + } catch (ZipException e) { + reportException(e); + } catch (IOException e) { + reportException(e); + } + } + + return null; + } + + public static IWorkspaceRoot getWorkspace() { + return ResourcesPlugin.getWorkspace().getRoot(); + } + + private static IPath getWorkspacePath() { + return ResourcesPlugin.getWorkspace().getRoot().getFullPath(); + } + + private static void reportException(Exception e) { + // TODO: add to appropriate error log? Report differently ?? + e.printStackTrace(); + } + +} diff --git a/com.ibm.wala.eclipse.tests/com.ibm.wala.eclipse.tests/src/com/ibm/wala/eclipse/tests/WalaCGModelTest.java b/com.ibm.wala.eclipse.tests/com.ibm.wala.eclipse.tests/src/com/ibm/wala/eclipse/tests/WalaCGModelTest.java new file mode 100644 index 000000000..9c5d7ea24 --- /dev/null +++ b/com.ibm.wala.eclipse.tests/com.ibm.wala.eclipse.tests/src/com/ibm/wala/eclipse/tests/WalaCGModelTest.java @@ -0,0 +1,53 @@ +/******************************************************************************* + * 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.eclipse.tests; + +import java.util.Collection; + +import junit.framework.TestCase; + +import org.eclipse.jdt.core.JavaModelException; + +import com.ibm.wala.eclipse.cg.model.WalaCGModelWithMain; +import com.ibm.wala.eclipse.util.JdtUtil; +import com.ibm.wala.util.graph.Graph; +import com.ibm.wala.util.warnings.WalaException; + +/** + * Smoke test on the Wala call graph Eclipse view + * + * @author aying + */ +public class WalaCGModelTest extends TestCase { + + @Override + public void setUp() { + System.out.println("Importing projects into the test workspace"); + EclipseTestUtil.importZippedProject("HelloWorld.zip"); + } + + public void testSmokeTest() throws WalaException, JavaModelException { + // get the input + String appJarFullPath = JdtUtil.getHelloWorldJar().getRawLocation().toString(); + + // compute the call graph + WalaCGModelWithMain model = new WalaCGModelWithMain(appJarFullPath); + model.buildGraph(); + + Collection roots = model.getRoots(); + assertNotNull(roots); + + Graph graph = model.getGraph(); + assertEquals(6, graph.getNumberOfNodes()); + } + +} diff --git a/com.ibm.wala.eclipse.tests/com.ibm.wala.eclipse.tests/testdata/HelloWorld.zip b/com.ibm.wala.eclipse.tests/com.ibm.wala.eclipse.tests/testdata/HelloWorld.zip new file mode 100644 index 000000000..4d5da5aed Binary files /dev/null and b/com.ibm.wala.eclipse.tests/com.ibm.wala.eclipse.tests/testdata/HelloWorld.zip differ diff --git a/com.ibm.wala.eclipse.tests/javaCompiler...args b/com.ibm.wala.eclipse.tests/javaCompiler...args new file mode 100644 index 000000000..5b5529e0e --- /dev/null +++ b/com.ibm.wala.eclipse.tests/javaCompiler...args @@ -0,0 +1,77 @@ +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.ui_3.2.0.I20060605-1400.jar[~org/eclipse/ui/internal/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.core.runtime_3.2.0.v20060603.jar[~org/eclipse/core/internal/preferences/legacy/*;~org/eclipse/core/internal/runtime/*;+org/eclipse/core/runtime/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.osgi_3.2.0.v20060601.jar[+org/eclipse/osgi/event/*;+org/eclipse/osgi/framework/console/*;+org/eclipse/osgi/framework/eventmgr/*;+org/eclipse/osgi/framework/log/*;+org/eclipse/osgi/service/datalocation/*;+org/eclipse/osgi/service/debug/*;+org/eclipse/osgi/service/environment/*;+org/eclipse/osgi/service/localization/*;+org/eclipse/osgi/service/pluginconversion/*;+org/eclipse/osgi/service/resolver/*;+org/eclipse/osgi/service/runnable/*;+org/eclipse/osgi/service/urlconversion/*;+org/eclipse/osgi/storagemanager/*;+org/eclipse/osgi/util/*;+org/osgi/framework/*;+org/osgi/service/condpermadmin/*;+org/osgi/service/packageadmin/*;+org/osgi/service/permissionadmin/*;+org/osgi/service/startlevel/*;+org/osgi/service/url/*;+org/osgi/util/tracker/*;~org/eclipse/core/runtime/adaptor/*;~org/eclipse/core/runtime/internal/adaptor/*;~org/eclipse/core/runtime/internal/stats/*;~org/eclipse/osgi/baseadaptor/*;~org/eclipse/osgi/baseadaptor/bundlefile/*;~org/eclipse/osgi/baseadaptor/hooks/*;~org/eclipse/osgi/baseadaptor/loader/*;~org/eclipse/osgi/framework/adaptor/*;~org/eclipse/osgi/framework/debug/*;~org/eclipse/osgi/framework/internal/core/*;~org/eclipse/osgi/framework/internal/protocol/*;~org/eclipse/osgi/framework/internal/protocol/bundleentry/*;~org/eclipse/osgi/framework/internal/protocol/bundleresource/*;~org/eclipse/osgi/framework/internal/protocol/reference/*;~org/eclipse/osgi/framework/internal/reliablefile/*;~org/eclipse/osgi/framework/launcher/*;~org/eclipse/osgi/framework/util/*;~org/eclipse/osgi/internal/baseadaptor/*;~org/eclipse/osgi/internal/module/*;~org/eclipse/osgi/internal/profile/*;~org/eclipse/osgi/internal/resolver/*;~org/eclipse/osgi/internal/verifier/*;~org/eclipse/osgi/internal/provisional/verifier/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.equinox.common_3.2.0.v20060603.jar[~org/eclipse/core/internal/runtime/*;~org/eclipse/core/internal/boot/*;+org/eclipse/core/runtime/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.core.jobs_3.2.0.v20060603.jar[~org/eclipse/core/internal/jobs/*;+org/eclipse/core/runtime/jobs/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.core.runtime.compatibility.registry_3.2.0.v20060603/runtime_registry_compatibility.jar[~org/eclipse/core/internal/registry/*;~org/eclipse/core/internal/registry/osgi/*;~org/eclipse/core/internal/registry/spi/*;+org/eclipse/core/runtime/*;+org/eclipse/core/runtime/dynamichelpers/*;+org/eclipse/core/runtime/spi/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.core.runtime.compatibility.registry_3.2.0.v20060603[~org/eclipse/core/internal/registry/*;~org/eclipse/core/internal/registry/osgi/*;~org/eclipse/core/internal/registry/spi/*;+org/eclipse/core/runtime/*;+org/eclipse/core/runtime/dynamichelpers/*;+org/eclipse/core/runtime/spi/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.equinox.registry_3.2.0.v20060601.jar[~org/eclipse/core/internal/registry/*;~org/eclipse/core/internal/registry/osgi/*;~org/eclipse/core/internal/registry/spi/*;+org/eclipse/core/runtime/*;+org/eclipse/core/runtime/dynamichelpers/*;+org/eclipse/core/runtime/spi/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.apache.xerces_2.8.0.v200606131651/resolver.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.apache.xerces_2.8.0.v200606131651/xercesImpl.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.apache.xerces_2.8.0.v200606131651/xml-apis.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.equinox.preferences_3.2.0.v20060601.jar[~org/eclipse/core/internal/preferences/*;~org/eclipse/core/internal/preferences/exchange/*;+org/eclipse/core/runtime/preferences/*;+org/osgi/service/prefs/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.core.runtime.compatibility.registry_3.2.0.v20060603/@dot[~org/eclipse/core/internal/registry/*;~org/eclipse/core/internal/registry/osgi/*;~org/eclipse/core/internal/registry/spi/*;+org/eclipse/core/runtime/*;+org/eclipse/core/runtime/dynamichelpers/*;+org/eclipse/core/runtime/spi/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.core.contenttype_3.2.0.v20060603.jar[~org/eclipse/core/internal/content/*;+org/eclipse/core/runtime/content/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.core.runtime.compatibility.auth_3.2.0.v20060601.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.swt_3.2.0.v3232o.jar[+org/eclipse/swt/*;+org/eclipse/swt/accessibility/*;+org/eclipse/swt/awt/*;+org/eclipse/swt/browser/*;+org/eclipse/swt/custom/*;+org/eclipse/swt/dnd/*;+org/eclipse/swt/events/*;+org/eclipse/swt/graphics/*;+org/eclipse/swt/layout/*;+org/eclipse/swt/opengl/*;+org/eclipse/swt/printing/*;+org/eclipse/swt/program/*;+org/eclipse/swt/widgets/*;~org/eclipse/swt/internal/*;~org/eclipse/swt/internal/image/*;~org/eclipse/swt/internal/theme/*;+org/eclipse/swt/ole/win32/*;~org/eclipse/swt/internal/gdip/*;~org/eclipse/swt/internal/ole/win32/*;~org/eclipse/swt/internal/win32/*;~org/eclipse/swt/internal/opengl/win32/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.swt.win32.win32.x86_3.2.0.v3232m.jar[+org/eclipse/swt/*;+org/eclipse/swt/accessibility/*;+org/eclipse/swt/awt/*;+org/eclipse/swt/browser/*;+org/eclipse/swt/custom/*;+org/eclipse/swt/dnd/*;+org/eclipse/swt/events/*;+org/eclipse/swt/graphics/*;+org/eclipse/swt/layout/*;+org/eclipse/swt/opengl/*;+org/eclipse/swt/printing/*;+org/eclipse/swt/program/*;+org/eclipse/swt/widgets/*;~org/eclipse/swt/internal/*;~org/eclipse/swt/internal/image/*;~org/eclipse/swt/internal/theme/*;+org/eclipse/swt/ole/win32/*;~org/eclipse/swt/internal/gdip/*;~org/eclipse/swt/internal/ole/win32/*;~org/eclipse/swt/internal/win32/*;~org/eclipse/swt/internal/opengl/win32/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.jface_3.2.0.I20060605-1400.jar[+org/eclipse/jface/*;+org/eclipse/jface/action/*;+org/eclipse/jface/action/images/*;+org/eclipse/jface/bindings/*;+org/eclipse/jface/bindings/keys/*;+org/eclipse/jface/bindings/keys/formatting/*;+org/eclipse/jface/commands/*;+org/eclipse/jface/contexts/*;+org/eclipse/jface/dialogs/*;+org/eclipse/jface/dialogs/images/*;+org/eclipse/jface/fieldassist/*;+org/eclipse/jface/fieldassist/images/*;+org/eclipse/jface/images/*;~org/eclipse/jface/internal/provisional/action/*;+org/eclipse/jface/layout/*;+org/eclipse/jface/menus/*;+org/eclipse/jface/operation/*;+org/eclipse/jface/preference/*;+org/eclipse/jface/preference/images/*;+org/eclipse/jface/resource/*;+org/eclipse/jface/util/*;+org/eclipse/jface/viewers/*;+org/eclipse/jface/viewers/deferred/*;+org/eclipse/jface/window/*;+org/eclipse/jface/wizard/*;+org/eclipse/jface/wizard/images/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.core.commands_3.2.0.I20060605-1400.jar[+org/eclipse/core/commands/*;+org/eclipse/core/commands/common/*;+org/eclipse/core/commands/contexts/*;+org/eclipse/core/commands/operations/*;+org/eclipse/core/commands/util/*;~org/eclipse/core/internal/commands/operations/*;~org/eclipse/core/internal/commands/util/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.ui.workbench_3.2.0.I20060605-1400.jar[+org/eclipse/ui/*;+org/eclipse/ui/about/*;+org/eclipse/ui/actions/*;+org/eclipse/ui/activities/*;+org/eclipse/ui/application/*;+org/eclipse/ui/branding/*;+org/eclipse/ui/browser/*;+org/eclipse/ui/commands/*;+org/eclipse/ui/contexts/*;+org/eclipse/ui/dialogs/*;+org/eclipse/ui/fieldassist/*;+org/eclipse/ui/handlers/*;+org/eclipse/ui/help/*;~org/eclipse/ui/internal/*;~org/eclipse/ui/internal/about/*;~org/eclipse/ui/internal/actions/*;~org/eclipse/ui/internal/activities/*;~org/eclipse/ui/internal/activities/ws/*;~org/eclipse/ui/internal/application/*;~org/eclipse/ui/internal/browser/*;~org/eclipse/ui/internal/commands/*;~org/eclipse/ui/internal/contexts/*;~org/eclipse/ui/internal/decorators/*;~org/eclipse/ui/internal/dialogs/*;~org/eclipse/ui/internal/dnd/*;~org/eclipse/ui/internal/editorsupport/*;~org/eclipse/ui/internal/expressions/*;~org/eclipse/ui/internal/handlers/*;~org/eclipse/ui/internal/help/*;~org/eclipse/ui/internal/intro/*;~org/eclipse/ui/internal/keys/*;~org/eclipse/ui/internal/layout/*;~org/eclipse/ui/internal/menus/*;~org/eclipse/ui/internal/misc/*;~org/eclipse/ui/internal/operations/*;~org/eclipse/ui/internal/part/*;~org/eclipse/ui/internal/preferences/*;~org/eclipse/ui/internal/presentations/*;~org/eclipse/ui/internal/presentations/defaultpresentation/*;~org/eclipse/ui/internal/presentations/util/*;~org/eclipse/ui/internal/progress/*;~org/eclipse/ui/internal/provisional/application/*;~org/eclipse/ui/internal/provisional/presentations/*;~org/eclipse/ui/internal/registry/*;~org/eclipse/ui/internal/services/*;~org/eclipse/ui/internal/testing/*;~org/eclipse/ui/internal/themes/*;~org/eclipse/ui/internal/util/*;~org/eclipse/ui/internal/wizards/*;~org/eclipse/ui/internal/wizards/preferences/*;+org/eclipse/ui/intro/*;+org/eclipse/ui/keys/*;+org/eclipse/ui/menus/*;+org/eclipse/ui/model/*;+org/eclipse/ui/operations/*;+org/eclipse/ui/part/*;+org/eclipse/ui/plugin/*;+org/eclipse/ui/preferences/*;+org/eclipse/ui/presentations/*;+org/eclipse/ui/progress/*;+org/eclipse/ui/services/*;+org/eclipse/ui/testing/*;+org/eclipse/ui/themes/*;+org/eclipse/ui/views/*;+org/eclipse/ui/wizards/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.ui.workbench.compatibility_3.2.0.I20060605-1400/@dot[+org/eclipse/ui/*;+org/eclipse/ui/about/*;+org/eclipse/ui/actions/*;+org/eclipse/ui/activities/*;+org/eclipse/ui/application/*;+org/eclipse/ui/branding/*;+org/eclipse/ui/browser/*;+org/eclipse/ui/commands/*;+org/eclipse/ui/contexts/*;+org/eclipse/ui/dialogs/*;+org/eclipse/ui/fieldassist/*;+org/eclipse/ui/handlers/*;+org/eclipse/ui/help/*;~org/eclipse/ui/internal/*;~org/eclipse/ui/internal/about/*;~org/eclipse/ui/internal/actions/*;~org/eclipse/ui/internal/activities/*;~org/eclipse/ui/internal/activities/ws/*;~org/eclipse/ui/internal/application/*;~org/eclipse/ui/internal/browser/*;~org/eclipse/ui/internal/commands/*;~org/eclipse/ui/internal/contexts/*;~org/eclipse/ui/internal/decorators/*;~org/eclipse/ui/internal/dialogs/*;~org/eclipse/ui/internal/dnd/*;~org/eclipse/ui/internal/editorsupport/*;~org/eclipse/ui/internal/expressions/*;~org/eclipse/ui/internal/handlers/*;~org/eclipse/ui/internal/help/*;~org/eclipse/ui/internal/intro/*;~org/eclipse/ui/internal/keys/*;~org/eclipse/ui/internal/layout/*;~org/eclipse/ui/internal/menus/*;~org/eclipse/ui/internal/misc/*;~org/eclipse/ui/internal/operations/*;~org/eclipse/ui/internal/part/*;~org/eclipse/ui/internal/preferences/*;~org/eclipse/ui/internal/presentations/*;~org/eclipse/ui/internal/presentations/defaultpresentation/*;~org/eclipse/ui/internal/presentations/util/*;~org/eclipse/ui/internal/progress/*;~org/eclipse/ui/internal/provisional/application/*;~org/eclipse/ui/internal/provisional/presentations/*;~org/eclipse/ui/internal/registry/*;~org/eclipse/ui/internal/services/*;~org/eclipse/ui/internal/testing/*;~org/eclipse/ui/internal/themes/*;~org/eclipse/ui/internal/util/*;~org/eclipse/ui/internal/wizards/*;~org/eclipse/ui/internal/wizards/preferences/*;+org/eclipse/ui/intro/*;+org/eclipse/ui/keys/*;+org/eclipse/ui/menus/*;+org/eclipse/ui/model/*;+org/eclipse/ui/operations/*;+org/eclipse/ui/part/*;+org/eclipse/ui/plugin/*;+org/eclipse/ui/preferences/*;+org/eclipse/ui/presentations/*;+org/eclipse/ui/progress/*;+org/eclipse/ui/services/*;+org/eclipse/ui/testing/*;+org/eclipse/ui/themes/*;+org/eclipse/ui/views/*;+org/eclipse/ui/wizards/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.ui.workbench.compatibility_3.2.0.I20060605-1400/compatibility.jar[+org/eclipse/ui/*;+org/eclipse/ui/about/*;+org/eclipse/ui/actions/*;+org/eclipse/ui/activities/*;+org/eclipse/ui/application/*;+org/eclipse/ui/branding/*;+org/eclipse/ui/browser/*;+org/eclipse/ui/commands/*;+org/eclipse/ui/contexts/*;+org/eclipse/ui/dialogs/*;+org/eclipse/ui/fieldassist/*;+org/eclipse/ui/handlers/*;+org/eclipse/ui/help/*;~org/eclipse/ui/internal/*;~org/eclipse/ui/internal/about/*;~org/eclipse/ui/internal/actions/*;~org/eclipse/ui/internal/activities/*;~org/eclipse/ui/internal/activities/ws/*;~org/eclipse/ui/internal/application/*;~org/eclipse/ui/internal/browser/*;~org/eclipse/ui/internal/commands/*;~org/eclipse/ui/internal/contexts/*;~org/eclipse/ui/internal/decorators/*;~org/eclipse/ui/internal/dialogs/*;~org/eclipse/ui/internal/dnd/*;~org/eclipse/ui/internal/editorsupport/*;~org/eclipse/ui/internal/expressions/*;~org/eclipse/ui/internal/handlers/*;~org/eclipse/ui/internal/help/*;~org/eclipse/ui/internal/intro/*;~org/eclipse/ui/internal/keys/*;~org/eclipse/ui/internal/layout/*;~org/eclipse/ui/internal/menus/*;~org/eclipse/ui/internal/misc/*;~org/eclipse/ui/internal/operations/*;~org/eclipse/ui/internal/part/*;~org/eclipse/ui/internal/preferences/*;~org/eclipse/ui/internal/presentations/*;~org/eclipse/ui/internal/presentations/defaultpresentation/*;~org/eclipse/ui/internal/presentations/util/*;~org/eclipse/ui/internal/progress/*;~org/eclipse/ui/internal/provisional/application/*;~org/eclipse/ui/internal/provisional/presentations/*;~org/eclipse/ui/internal/registry/*;~org/eclipse/ui/internal/services/*;~org/eclipse/ui/internal/testing/*;~org/eclipse/ui/internal/themes/*;~org/eclipse/ui/internal/util/*;~org/eclipse/ui/internal/wizards/*;~org/eclipse/ui/internal/wizards/preferences/*;+org/eclipse/ui/intro/*;+org/eclipse/ui/keys/*;+org/eclipse/ui/menus/*;+org/eclipse/ui/model/*;+org/eclipse/ui/operations/*;+org/eclipse/ui/part/*;+org/eclipse/ui/plugin/*;+org/eclipse/ui/preferences/*;+org/eclipse/ui/presentations/*;+org/eclipse/ui/progress/*;+org/eclipse/ui/services/*;+org/eclipse/ui/testing/*;+org/eclipse/ui/themes/*;+org/eclipse/ui/views/*;+org/eclipse/ui/wizards/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/com.ibm.icu_3.4.4.1.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.help_3.2.0.v20060602.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.core.expressions_3.2.0.v20060605-1400.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.core.resources_3.2.0.v20060603.jar[~org/eclipse/core/internal/dtree/*;~org/eclipse/core/internal/events/*;~org/eclipse/core/internal/localstore/*;~org/eclipse/core/internal/properties/*;~org/eclipse/core/internal/propertytester/*;~org/eclipse/core/internal/refresh/*;~org/eclipse/core/internal/resources/*;~org/eclipse/core/internal/resources/mapping/*;~org/eclipse/core/internal/utils/*;~org/eclipse/core/internal/watson/*;+org/eclipse/core/resources/*;+org/eclipse/core/resources/mapping/*;+org/eclipse/core/resources/refresh/*;+org/eclipse/core/resources/team/*;~org/eclipse/core/internal/indexing/*;~org/eclipse/core/internal/resources/refresh/win32/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.core.resources.compatibility_3.2.0.v20060603.jar[~org/eclipse/core/internal/dtree/*;~org/eclipse/core/internal/events/*;~org/eclipse/core/internal/localstore/*;~org/eclipse/core/internal/properties/*;~org/eclipse/core/internal/propertytester/*;~org/eclipse/core/internal/refresh/*;~org/eclipse/core/internal/resources/*;~org/eclipse/core/internal/resources/mapping/*;~org/eclipse/core/internal/utils/*;~org/eclipse/core/internal/watson/*;+org/eclipse/core/resources/*;+org/eclipse/core/resources/mapping/*;+org/eclipse/core/resources/refresh/*;+org/eclipse/core/resources/team/*;~org/eclipse/core/internal/indexing/*;~org/eclipse/core/internal/resources/refresh/win32/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.core.resources.win32_3.2.0.v20060603.jar[~org/eclipse/core/internal/dtree/*;~org/eclipse/core/internal/events/*;~org/eclipse/core/internal/localstore/*;~org/eclipse/core/internal/properties/*;~org/eclipse/core/internal/propertytester/*;~org/eclipse/core/internal/refresh/*;~org/eclipse/core/internal/resources/*;~org/eclipse/core/internal/resources/mapping/*;~org/eclipse/core/internal/utils/*;~org/eclipse/core/internal/watson/*;+org/eclipse/core/resources/*;+org/eclipse/core/resources/mapping/*;+org/eclipse/core/resources/refresh/*;+org/eclipse/core/resources/team/*;~org/eclipse/core/internal/indexing/*;~org/eclipse/core/internal/resources/refresh/win32/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.core.runtime.compatibility_3.1.100.v20060603.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.update.configurator_3.2.0.v20060605.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.ant.core_3.1.100.v20060531.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.core.variables_3.1.100.v20060605.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.core.filesystem_1.0.0.v20060603.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.core.filesystem.win32.x86_1.0.0.v20060603.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.jdt.core_3.2.0.v_671.jar[+org/eclipse/jdt/core/*;+org/eclipse/jdt/core/compiler/*;+org/eclipse/jdt/core/dom/*;+org/eclipse/jdt/core/dom/rewrite/*;+org/eclipse/jdt/core/eval/*;+org/eclipse/jdt/core/formatter/*;+org/eclipse/jdt/core/jdom/*;+org/eclipse/jdt/core/search/*;+org/eclipse/jdt/core/util/*;~org/eclipse/jdt/internal/codeassist/*;~org/eclipse/jdt/internal/codeassist/complete/*;~org/eclipse/jdt/internal/codeassist/impl/*;~org/eclipse/jdt/internal/codeassist/select/*;~org/eclipse/jdt/internal/compiler/*;~org/eclipse/jdt/internal/compiler/ast/*;~org/eclipse/jdt/internal/compiler/batch/*;~org/eclipse/jdt/internal/compiler/classfmt/*;~org/eclipse/jdt/internal/compiler/codegen/*;~org/eclipse/jdt/internal/compiler/env/*;~org/eclipse/jdt/internal/compiler/flow/*;~org/eclipse/jdt/internal/compiler/impl/*;~org/eclipse/jdt/internal/compiler/lookup/*;~org/eclipse/jdt/internal/compiler/parser/*;~org/eclipse/jdt/internal/compiler/parser/diagnose/*;~org/eclipse/jdt/internal/compiler/problem/*;~org/eclipse/jdt/internal/compiler/util/*;~org/eclipse/jdt/internal/core/*;~org/eclipse/jdt/internal/core/builder/*;~org/eclipse/jdt/internal/core/dom/rewrite/*;~org/eclipse/jdt/internal/core/eval/*;~org/eclipse/jdt/internal/core/hierarchy/*;~org/eclipse/jdt/internal/core/index/*;~org/eclipse/jdt/internal/core/jdom/*;~org/eclipse/jdt/internal/core/search/*;~org/eclipse/jdt/internal/core/search/indexing/*;~org/eclipse/jdt/internal/core/search/matching/*;~org/eclipse/jdt/internal/core/search/processing/*;~org/eclipse/jdt/internal/core/util/*;~org/eclipse/jdt/internal/eval/*;~org/eclipse/jdt/internal/formatter/*;~org/eclipse/jdt/internal/formatter/align/*;~org/eclipse/jdt/internal/formatter/comment/*;~org/eclipse/jdt/internal/formatter/old/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.text_3.2.0.v20060605-1400.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.team.core_3.2.0.I200606051140.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.ui.ide_3.2.0.I20060605-1400.jar[+org/eclipse/ui/*;+org/eclipse/ui/actions/*;+org/eclipse/ui/dialogs/*;+org/eclipse/ui/ide/*;+org/eclipse/ui/ide/dialogs/*;+org/eclipse/ui/ide/fileSystem/*;~org/eclipse/ui/internal/ide/*;~org/eclipse/ui/internal/ide/actions/*;~org/eclipse/ui/internal/ide/commands/*;~org/eclipse/ui/internal/ide/dialogs/*;~org/eclipse/ui/internal/ide/filesystem/*;~org/eclipse/ui/internal/ide/handlers/*;~org/eclipse/ui/internal/ide/misc/*;~org/eclipse/ui/internal/ide/model/*;~org/eclipse/ui/internal/ide/registry/*;~org/eclipse/ui/internal/ide/update/*;~org/eclipse/ui/internal/views/bookmarkexplorer/*;~org/eclipse/ui/internal/views/framelist/*;~org/eclipse/ui/internal/views/navigator/*;~org/eclipse/ui/internal/views/properties/*;~org/eclipse/ui/internal/views/tasklist/*;~org/eclipse/ui/internal/wizards/datatransfer/*;~org/eclipse/ui/internal/wizards/newresource/*;+org/eclipse/ui/model/*;+org/eclipse/ui/part/*;+org/eclipse/ui/views/bookmarkexplorer/*;+org/eclipse/ui/views/framelist/*;+org/eclipse/ui/views/markers/*;~org/eclipse/ui/views/markers/internal/*;+org/eclipse/ui/views/navigator/*;+org/eclipse/ui/views/properties/*;+org/eclipse/ui/views/tasklist/*;+org/eclipse/ui/wizards/datatransfer/*;+org/eclipse/ui/wizards/newresource/*;~org/eclipse/ui/internal/editorsupport/win32/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.ui.win32_3.2.0.I20060605-1400.jar[+org/eclipse/ui/*;+org/eclipse/ui/actions/*;+org/eclipse/ui/dialogs/*;+org/eclipse/ui/ide/*;+org/eclipse/ui/ide/dialogs/*;+org/eclipse/ui/ide/fileSystem/*;~org/eclipse/ui/internal/ide/*;~org/eclipse/ui/internal/ide/actions/*;~org/eclipse/ui/internal/ide/commands/*;~org/eclipse/ui/internal/ide/dialogs/*;~org/eclipse/ui/internal/ide/filesystem/*;~org/eclipse/ui/internal/ide/handlers/*;~org/eclipse/ui/internal/ide/misc/*;~org/eclipse/ui/internal/ide/model/*;~org/eclipse/ui/internal/ide/registry/*;~org/eclipse/ui/internal/ide/update/*;~org/eclipse/ui/internal/views/bookmarkexplorer/*;~org/eclipse/ui/internal/views/framelist/*;~org/eclipse/ui/internal/views/navigator/*;~org/eclipse/ui/internal/views/properties/*;~org/eclipse/ui/internal/views/tasklist/*;~org/eclipse/ui/internal/wizards/datatransfer/*;~org/eclipse/ui/internal/wizards/newresource/*;+org/eclipse/ui/model/*;+org/eclipse/ui/part/*;+org/eclipse/ui/views/bookmarkexplorer/*;+org/eclipse/ui/views/framelist/*;+org/eclipse/ui/views/markers/*;~org/eclipse/ui/views/markers/internal/*;+org/eclipse/ui/views/navigator/*;+org/eclipse/ui/views/properties/*;+org/eclipse/ui/views/tasklist/*;+org/eclipse/ui/wizards/datatransfer/*;+org/eclipse/ui/wizards/newresource/*;~org/eclipse/ui/internal/editorsupport/win32/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.ui.views_3.2.0.I20060605-1400.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.update.core_3.2.0.v20060605.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.update.core.win32_3.2.0.v20060605.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.update.ui_3.2.0.v20060605.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.ui.forms_3.2.0.v20060602.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.junit_3.8.1/junit.jar[+junit/awtui/*;+junit/extensions/*;+junit/framework/*;+junit/runner/*;+junit/swingui/*;+junit/swingui/icons/*;+junit/textui/*;?**/*] +#ADAPTER#ACCESS#com.ibm.wala.core/bin/[+com/ibm/wala/analysis/pointers/*;+com/ibm/wala/analysis/reflection/*;+com/ibm/wala/analysis/stackMachine/*;+com/ibm/wala/analysis/typeInference/*;+com/ibm/wala/cfg/*;+com/ibm/wala/cfg/cdg/*;+com/ibm/wala/classLoader/*;+com/ibm/wala/client/*;+com/ibm/wala/client/impl/*;+com/ibm/wala/core/plugin/*;+com/ibm/wala/dataflow/IFDS/*;+com/ibm/wala/dataflow/graph/*;+com/ibm/wala/dataflow/ssa/*;+com/ibm/wala/dynamic/*;+com/ibm/wala/emf/wrappers/*;+com/ibm/wala/escape/*;+com/ibm/wala/fixedpoint/impl/*;+com/ibm/wala/fixpoint/*;+com/ibm/wala/ipa/callgraph/*;+com/ibm/wala/ipa/callgraph/impl/*;+com/ibm/wala/ipa/callgraph/propagation/*;+com/ibm/wala/ipa/callgraph/propagation/cfa/*;+com/ibm/wala/ipa/callgraph/propagation/rta/*;+com/ibm/wala/ipa/cfg/*;+com/ibm/wala/ipa/cha/*;+com/ibm/wala/ipa/summaries/*;+com/ibm/wala/model/*;+com/ibm/wala/model/java/lang/*;+com/ibm/wala/properties/*;+com/ibm/wala/ssa/*;+com/ibm/wala/ssa/analysis/*;+com/ibm/wala/types/*;+com/ibm/wala/util/*;+com/ibm/wala/util/bytecode/*;+com/ibm/wala/util/collections/*;+com/ibm/wala/util/config/*;+com/ibm/wala/util/debug/*;+com/ibm/wala/util/graph/*;+com/ibm/wala/util/graph/impl/*;+com/ibm/wala/util/graph/traverse/*;+com/ibm/wala/util/heapTrace/*;+com/ibm/wala/util/intertionalization/*;+com/ibm/wala/util/intset/*;+com/ibm/wala/util/io/*;+com/ibm/wala/util/logging/*;+com/ibm/wala/util/math/*;+com/ibm/wala/util/perf/*;+com/ibm/wala/util/system/*;+com/ibm/wala/util/warnings/*;+com/ibm/wala/viz/*;?**/*] +#ADAPTER#ACCESS#com.ibm.wala.core/@dot[+com/ibm/wala/analysis/pointers/*;+com/ibm/wala/analysis/reflection/*;+com/ibm/wala/analysis/stackMachine/*;+com/ibm/wala/analysis/typeInference/*;+com/ibm/wala/cfg/*;+com/ibm/wala/cfg/cdg/*;+com/ibm/wala/classLoader/*;+com/ibm/wala/client/*;+com/ibm/wala/client/impl/*;+com/ibm/wala/core/plugin/*;+com/ibm/wala/dataflow/IFDS/*;+com/ibm/wala/dataflow/graph/*;+com/ibm/wala/dataflow/ssa/*;+com/ibm/wala/dynamic/*;+com/ibm/wala/emf/wrappers/*;+com/ibm/wala/escape/*;+com/ibm/wala/fixedpoint/impl/*;+com/ibm/wala/fixpoint/*;+com/ibm/wala/ipa/callgraph/*;+com/ibm/wala/ipa/callgraph/impl/*;+com/ibm/wala/ipa/callgraph/propagation/*;+com/ibm/wala/ipa/callgraph/propagation/cfa/*;+com/ibm/wala/ipa/callgraph/propagation/rta/*;+com/ibm/wala/ipa/cfg/*;+com/ibm/wala/ipa/cha/*;+com/ibm/wala/ipa/summaries/*;+com/ibm/wala/model/*;+com/ibm/wala/model/java/lang/*;+com/ibm/wala/properties/*;+com/ibm/wala/ssa/*;+com/ibm/wala/ssa/analysis/*;+com/ibm/wala/types/*;+com/ibm/wala/util/*;+com/ibm/wala/util/bytecode/*;+com/ibm/wala/util/collections/*;+com/ibm/wala/util/config/*;+com/ibm/wala/util/debug/*;+com/ibm/wala/util/graph/*;+com/ibm/wala/util/graph/impl/*;+com/ibm/wala/util/graph/traverse/*;+com/ibm/wala/util/heapTrace/*;+com/ibm/wala/util/intertionalization/*;+com/ibm/wala/util/intset/*;+com/ibm/wala/util/io/*;+com/ibm/wala/util/logging/*;+com/ibm/wala/util/math/*;+com/ibm/wala/util/perf/*;+com/ibm/wala/util/system/*;+com/ibm/wala/util/warnings/*;+com/ibm/wala/viz/*;?**/*] +#ADAPTER#ACCESS#com.ibm.wala.emf/bin/[+com/ibm/wala/ecore/common/*;+com/ibm/wala/ecore/common/impl/*;+com/ibm/wala/ecore/common/util/*;+com/ibm/wala/ecore/graph/*;+com/ibm/wala/ecore/graph/impl/*;+com/ibm/wala/ecore/graph/util/*;+com/ibm/wala/ecore/j2ee/scope/*;+com/ibm/wala/ecore/j2ee/scope/impl/*;+com/ibm/wala/ecore/j2ee/scope/util/*;+com/ibm/wala/ecore/java/*;+com/ibm/wala/ecore/java/callGraph/*;+com/ibm/wala/ecore/java/callGraph/impl/*;+com/ibm/wala/ecore/java/callGraph/util/*;+com/ibm/wala/ecore/java/impl/*;+com/ibm/wala/ecore/java/pointerAnalysis/*;+com/ibm/wala/ecore/java/pointerAnalysis/impl/*;+com/ibm/wala/ecore/java/pointerAnalysis/util/*;+com/ibm/wala/ecore/java/scope/*;+com/ibm/wala/ecore/java/scope/impl/*;+com/ibm/wala/ecore/java/scope/util/*;+com/ibm/wala/ecore/java/util/*;+com/ibm/wala/ecore/perf/*;+com/ibm/wala/ecore/perf/impl/*;+com/ibm/wala/ecore/perf/util/*;+com/ibm/wala/ecore/regex/*;+com/ibm/wala/ecore/regex/impl/*;+com/ibm/wala/ecore/regex/util/*;?**/*] +#ADAPTER#ACCESS#com.ibm.wala.emf/@dot[+com/ibm/wala/ecore/common/*;+com/ibm/wala/ecore/common/impl/*;+com/ibm/wala/ecore/common/util/*;+com/ibm/wala/ecore/graph/*;+com/ibm/wala/ecore/graph/impl/*;+com/ibm/wala/ecore/graph/util/*;+com/ibm/wala/ecore/j2ee/scope/*;+com/ibm/wala/ecore/j2ee/scope/impl/*;+com/ibm/wala/ecore/j2ee/scope/util/*;+com/ibm/wala/ecore/java/*;+com/ibm/wala/ecore/java/callGraph/*;+com/ibm/wala/ecore/java/callGraph/impl/*;+com/ibm/wala/ecore/java/callGraph/util/*;+com/ibm/wala/ecore/java/impl/*;+com/ibm/wala/ecore/java/pointerAnalysis/*;+com/ibm/wala/ecore/java/pointerAnalysis/impl/*;+com/ibm/wala/ecore/java/pointerAnalysis/util/*;+com/ibm/wala/ecore/java/scope/*;+com/ibm/wala/ecore/java/scope/impl/*;+com/ibm/wala/ecore/java/scope/util/*;+com/ibm/wala/ecore/java/util/*;+com/ibm/wala/ecore/perf/*;+com/ibm/wala/ecore/perf/impl/*;+com/ibm/wala/ecore/perf/util/*;+com/ibm/wala/ecore/regex/*;+com/ibm/wala/ecore/regex/impl/*;+com/ibm/wala/ecore/regex/util/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.emf.ecore_2.2.0.v200606271057.jar[+org/eclipse/emf/ecore/*;+org/eclipse/emf/ecore/impl/*;+org/eclipse/emf/ecore/plugin/*;+org/eclipse/emf/ecore/resource/*;+org/eclipse/emf/ecore/resource/impl/*;+org/eclipse/emf/ecore/util/*;+org/eclipse/emf/ecore/xml/namespace/*;+org/eclipse/emf/ecore/xml/namespace/impl/*;+org/eclipse/emf/ecore/xml/namespace/util/*;+org/eclipse/emf/ecore/xml/type/*;+org/eclipse/emf/ecore/xml/type/impl/*;+org/eclipse/emf/ecore/xml/type/internal/*;+org/eclipse/emf/ecore/xml/type/util/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.emf.common_2.2.0.v200606271057.jar[+org/eclipse/emf/common/*;+org/eclipse/emf/common/archive/*;+org/eclipse/emf/common/command/*;+org/eclipse/emf/common/notify/*;+org/eclipse/emf/common/notify/impl/*;+org/eclipse/emf/common/util/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.emf.ecore.xmi_2.2.0.v200606271057.jar[+org/eclipse/emf/ecore/xmi/*;+org/eclipse/emf/ecore/xmi/impl/*;+org/eclipse/emf/ecore/xmi/util/*;?**/*] +#ADAPTER#ACCESS#com.ibm.wala.shrike/bin/[+com/ibm/wala/shrike/bench/*;+com/ibm/wala/shrike/copywriter/*;+com/ibm/wala/shrike/tools/*;+com/ibm/wala/shrikeBT/*;+com/ibm/wala/shrikeBT/analysis/*;+com/ibm/wala/shrikeBT/info/*;+com/ibm/wala/shrikeBT/shrikeCT/*;+com/ibm/wala/shrikeBT/shrikeCT/tools/*;+com/ibm/wala/shrikeBT/tools/*;+com/ibm/wala/shrikeCT/*;?**/*] +#ADAPTER#ACCESS#com.ibm.wala.shrike/@dot[+com/ibm/wala/shrike/bench/*;+com/ibm/wala/shrike/copywriter/*;+com/ibm/wala/shrike/tools/*;+com/ibm/wala/shrikeBT/*;+com/ibm/wala/shrikeBT/analysis/*;+com/ibm/wala/shrikeBT/info/*;+com/ibm/wala/shrikeBT/shrikeCT/*;+com/ibm/wala/shrikeBT/shrikeCT/tools/*;+com/ibm/wala/shrikeBT/tools/*;+com/ibm/wala/shrikeCT/*;?**/*] +#ADAPTER#ACCESS#com.ibm.wala.eclipse/bin/[+com/ibm/wala/eclipse/util/*;+com/ibm/wala/eclipse/views/cfg/*;?**/*] +#ADAPTER#ACCESS#com.ibm.wala.eclipse/@dot[+com/ibm/wala/eclipse/util/*;+com/ibm/wala/eclipse/views/cfg/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.jdt.ui_3.2.0.v20060605-1400.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.ui.console_3.1.100.v20060605.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.jface.text_3.2.0.v20060605-1400.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.ui.workbench.texteditor_3.2.0.v20060605-1400.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.search_3.2.0.v20060605-1400.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.core.filebuffers_3.2.0.v20060605-1400.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.debug.core_3.2.0.v20060605.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.debug.ui_3.2.0.v20060605.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.ui.editors_3.2.0.v20060605-1400.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.jdt.launching_3.2.0.v20060605.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.jdt.debug_3.2.0.v20060605/jdi.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.jdt.debug_3.2.0.v20060605/jdimodel.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.jdt.debug_3.2.0.v20060605/tools.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.compare_3.2.0.v20060605.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.team.ui_3.2.0.I200606051140.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.ui.navigator_3.2.0.I20060605-1400.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.ui.navigator.resources_3.2.0.I20060605-1400.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.ui.views.properties.tabbed_3.2.0.I20060605-1400.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.ltk.core.refactoring_3.2.0.v20060605-1400.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.ltk.ui.refactoring_3.2.0.v20060605-1400.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.jdt.core.manipulation_1.0.0.v20060605-1400.jar[?**/*] diff --git a/com.ibm.wala.eclipse.tests/launchers/wala.eclipse.tests.launch b/com.ibm.wala.eclipse.tests/launchers/wala.eclipse.tests.launch new file mode 100644 index 000000000..c3b6fa6f0 --- /dev/null +++ b/com.ibm.wala.eclipse.tests/launchers/wala.eclipse.tests.launch @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/com.ibm.wala.eclipse.tests/src/com/ibm/wala/eclipse/tests/Activator.java b/com.ibm.wala.eclipse.tests/src/com/ibm/wala/eclipse/tests/Activator.java new file mode 100644 index 000000000..292e08000 --- /dev/null +++ b/com.ibm.wala.eclipse.tests/src/com/ibm/wala/eclipse/tests/Activator.java @@ -0,0 +1,60 @@ +/******************************************************************************* + * 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.eclipse.tests; + +import org.eclipse.ui.plugin.AbstractUIPlugin; +import org.osgi.framework.BundleContext; + +/** + * The activator class controls the plug-in life cycle + */ +public class Activator extends AbstractUIPlugin { + + // The plug-in ID + public static final String PLUGIN_ID = "com.ibm.wala.eclipse.tests"; + + // The shared instance + private static Activator plugin; + + /** + * The constructor + */ + public Activator() { + plugin = this; + } + + /* + * (non-Javadoc) + * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext) + */ + public void start(BundleContext context) throws Exception { + super.start(context); + } + + /* + * (non-Javadoc) + * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext) + */ + public void stop(BundleContext context) throws Exception { + plugin = null; + super.stop(context); + } + + /** + * Returns the shared instance + * + * @return the shared instance + */ + public static Activator getDefault() { + return plugin; + } + +} diff --git a/com.ibm.wala.eclipse.tests/src/com/ibm/wala/eclipse/tests/EclipseTestUtil.java b/com.ibm.wala.eclipse.tests/src/com/ibm/wala/eclipse/tests/EclipseTestUtil.java new file mode 100644 index 000000000..78d8f25a2 --- /dev/null +++ b/com.ibm.wala.eclipse.tests/src/com/ibm/wala/eclipse/tests/EclipseTestUtil.java @@ -0,0 +1,131 @@ +/******************************************************************************* + * 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.eclipse.tests; + +import java.io.File; +import java.io.IOException; +import java.lang.reflect.InvocationTargetException; +import java.net.URL; +import java.util.List; +import java.util.zip.ZipException; +import java.util.zip.ZipFile; + +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IWorkspaceRoot; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.FileLocator; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.core.runtime.Path; +import org.eclipse.core.runtime.Platform; +import org.eclipse.ui.dialogs.IOverwriteQuery; +import org.eclipse.ui.wizards.datatransfer.ImportOperation; +import org.eclipse.ui.wizards.datatransfer.ZipFileStructureProvider; +import org.osgi.framework.Bundle; + +public class EclipseTestUtil { + + public static void importZippedProject(String zipFileName) { + ZipFile zipFile = getZipFile(zipFileName); + ZipFileStructureProvider zp = new ZipFileStructureProvider(zipFile); + List children = zp.getChildren(zp.getRoot()); + Object element = children.get(0); + String projectName = zp.getLabel(element); + createOpenProject(projectName); + importZipfile(zipFile,zp); + } + + public static void createOpenProject(String projectName) { + IWorkspaceRoot root = getWorkspace(); + IProject project = root.getProject(projectName); + try { + project.create(null); + project.open(null); + } catch (CoreException e) { + e.printStackTrace(); + } + } + + protected static void importZipfile(ZipFile sourceZip, ZipFileStructureProvider provider) { + IPath containerPath = getWorkspacePath(); + + ImportOperation importOp = new ImportOperation(containerPath,provider.getRoot(), provider, + new IOverwriteQuery() { + public String queryOverwrite(String pathString) { + return IOverwriteQuery.ALL; + } + } + ); + + importOp.setCreateContainerStructure(true); + importOp.setOverwriteResources(true); + try { + importOp.run(new NullProgressMonitor()); + } catch (InvocationTargetException e) { + e.printStackTrace(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + + try { + sourceZip.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + + public static File getTestDataFile(String filename) { + Bundle bundle = Platform.getBundle(Activator.PLUGIN_ID); + IPath path = new Path("testdata").append(filename); + + URL url = FileLocator.find(bundle, path, null); + try { + URL fileURL = FileLocator.toFileURL(url); + File file = new File(fileURL.getPath()); + return file; + } catch (IOException e) { + reportException(e); + } + + return null; + } + + public static ZipFile getZipFile(String testArchive) { + File file = getTestDataFile(testArchive); + if(file != null) { + try { + return new ZipFile(file); + } catch (ZipException e) { + reportException(e); + } catch (IOException e) { + reportException(e); + } + } + + return null; + } + + public static IWorkspaceRoot getWorkspace() { + return ResourcesPlugin.getWorkspace().getRoot(); + } + + private static IPath getWorkspacePath() { + return ResourcesPlugin.getWorkspace().getRoot().getFullPath(); + } + + private static void reportException(Exception e) { + // TODO: add to appropriate error log? Report differently ?? + e.printStackTrace(); + } + +} diff --git a/com.ibm.wala.eclipse.tests/src/com/ibm/wala/eclipse/tests/WalaCGModelTest.java b/com.ibm.wala.eclipse.tests/src/com/ibm/wala/eclipse/tests/WalaCGModelTest.java new file mode 100644 index 000000000..9c5d7ea24 --- /dev/null +++ b/com.ibm.wala.eclipse.tests/src/com/ibm/wala/eclipse/tests/WalaCGModelTest.java @@ -0,0 +1,53 @@ +/******************************************************************************* + * 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.eclipse.tests; + +import java.util.Collection; + +import junit.framework.TestCase; + +import org.eclipse.jdt.core.JavaModelException; + +import com.ibm.wala.eclipse.cg.model.WalaCGModelWithMain; +import com.ibm.wala.eclipse.util.JdtUtil; +import com.ibm.wala.util.graph.Graph; +import com.ibm.wala.util.warnings.WalaException; + +/** + * Smoke test on the Wala call graph Eclipse view + * + * @author aying + */ +public class WalaCGModelTest extends TestCase { + + @Override + public void setUp() { + System.out.println("Importing projects into the test workspace"); + EclipseTestUtil.importZippedProject("HelloWorld.zip"); + } + + public void testSmokeTest() throws WalaException, JavaModelException { + // get the input + String appJarFullPath = JdtUtil.getHelloWorldJar().getRawLocation().toString(); + + // compute the call graph + WalaCGModelWithMain model = new WalaCGModelWithMain(appJarFullPath); + model.buildGraph(); + + Collection roots = model.getRoots(); + assertNotNull(roots); + + Graph graph = model.getGraph(); + assertEquals(6, graph.getNumberOfNodes()); + } + +} diff --git a/com.ibm.wala.eclipse.tests/testdata/HelloWorld.zip b/com.ibm.wala.eclipse.tests/testdata/HelloWorld.zip new file mode 100644 index 000000000..4d5da5aed Binary files /dev/null and b/com.ibm.wala.eclipse.tests/testdata/HelloWorld.zip differ diff --git a/com.ibm.wala.eclipse/.classpath b/com.ibm.wala.eclipse/.classpath new file mode 100644 index 000000000..021596729 --- /dev/null +++ b/com.ibm.wala.eclipse/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/com.ibm.wala.eclipse/.project b/com.ibm.wala.eclipse/.project new file mode 100644 index 000000000..97833babd --- /dev/null +++ b/com.ibm.wala.eclipse/.project @@ -0,0 +1,28 @@ + + + com.ibm.wala.eclipse + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/com.ibm.wala.eclipse/.settings/org.eclipse.jdt.core.prefs b/com.ibm.wala.eclipse/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 000000000..1a3c52c26 --- /dev/null +++ b/com.ibm.wala.eclipse/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,62 @@ +#Tue Oct 10 11:39:40 EDT 2006 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5 +org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve +org.eclipse.jdt.core.compiler.compliance=1.5 +org.eclipse.jdt.core.compiler.debug.lineNumber=generate +org.eclipse.jdt.core.compiler.debug.localVariable=generate +org.eclipse.jdt.core.compiler.debug.sourceFile=generate +org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.autoboxing=ignore +org.eclipse.jdt.core.compiler.problem.deprecation=warning +org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled +org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled +org.eclipse.jdt.core.compiler.problem.discouragedReference=ignore +org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore +org.eclipse.jdt.core.compiler.problem.fieldHiding=ignore +org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning +org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning +org.eclipse.jdt.core.compiler.problem.forbiddenReference=error +org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning +org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning +org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=ignore +org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore +org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore +org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning +org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore +org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore +org.eclipse.jdt.core.compiler.problem.missingSerialVersion=ignore +org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning +org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning +org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore +org.eclipse.jdt.core.compiler.problem.nullReference=ignore +org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning +org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore +org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=ignore +org.eclipse.jdt.core.compiler.problem.rawTypeReference=ignore +org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled +org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning +org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled +org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore +org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning +org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning +org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore +org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning +org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore +org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=ignore +org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled +org.eclipse.jdt.core.compiler.problem.unusedImport=warning +org.eclipse.jdt.core.compiler.problem.unusedLabel=warning +org.eclipse.jdt.core.compiler.problem.unusedLocal=warning +org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore +org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled +org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled +org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning +org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning +org.eclipse.jdt.core.compiler.source=1.5 diff --git a/com.ibm.wala.eclipse/.settings/org.eclipse.jdt.ui.prefs b/com.ibm.wala.eclipse/.settings/org.eclipse.jdt.ui.prefs new file mode 100644 index 000000000..78efce42e --- /dev/null +++ b/com.ibm.wala.eclipse/.settings/org.eclipse.jdt.ui.prefs @@ -0,0 +1,3 @@ +#Tue Oct 10 11:07:11 EDT 2006 +eclipse.preferences.version=1 +internal.default.compliance=default diff --git a/com.ibm.wala.eclipse/META-INF/MANIFEST.MF b/com.ibm.wala.eclipse/META-INF/MANIFEST.MF new file mode 100644 index 000000000..eb32a744f --- /dev/null +++ b/com.ibm.wala.eclipse/META-INF/MANIFEST.MF @@ -0,0 +1,18 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Eclipse Plug-in +Bundle-SymbolicName: com.ibm.wala.eclipse;singleton:=true +Bundle-Version: 1.0.0 +Bundle-Activator: com.ibm.wala.eclipse.Activator +Bundle-Vendor: IBM +Bundle-Localization: plugin +Require-Bundle: org.eclipse.ui, + org.eclipse.core.runtime, + org.eclipse.core.resources, + org.eclipse.jdt.core, + org.eclipse.jdt.ui, + com.ibm.wala.core +Eclipse-LazyStart: true +Export-Package: com.ibm.wala.eclipse.cg.model, + com.ibm.wala.eclipse.cg.views, + com.ibm.wala.eclipse.util diff --git a/com.ibm.wala.eclipse/build.properties b/com.ibm.wala.eclipse/build.properties new file mode 100644 index 000000000..6f20375d6 --- /dev/null +++ b/com.ibm.wala.eclipse/build.properties @@ -0,0 +1,5 @@ +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + .,\ + plugin.xml diff --git a/com.ibm.wala.eclipse/build.xml b/com.ibm.wala.eclipse/build.xml new file mode 100644 index 000000000..385eaa143 --- /dev/null +++ b/com.ibm.wala.eclipse/build.xml @@ -0,0 +1,228 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/com.ibm.wala.eclipse/com.ibm.wala.eclipse/.classpath b/com.ibm.wala.eclipse/com.ibm.wala.eclipse/.classpath new file mode 100644 index 000000000..021596729 --- /dev/null +++ b/com.ibm.wala.eclipse/com.ibm.wala.eclipse/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/com.ibm.wala.eclipse/com.ibm.wala.eclipse/.project b/com.ibm.wala.eclipse/com.ibm.wala.eclipse/.project new file mode 100644 index 000000000..97833babd --- /dev/null +++ b/com.ibm.wala.eclipse/com.ibm.wala.eclipse/.project @@ -0,0 +1,28 @@ + + + com.ibm.wala.eclipse + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/com.ibm.wala.eclipse/com.ibm.wala.eclipse/.settings/org.eclipse.jdt.core.prefs b/com.ibm.wala.eclipse/com.ibm.wala.eclipse/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 000000000..1a3c52c26 --- /dev/null +++ b/com.ibm.wala.eclipse/com.ibm.wala.eclipse/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,62 @@ +#Tue Oct 10 11:39:40 EDT 2006 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5 +org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve +org.eclipse.jdt.core.compiler.compliance=1.5 +org.eclipse.jdt.core.compiler.debug.lineNumber=generate +org.eclipse.jdt.core.compiler.debug.localVariable=generate +org.eclipse.jdt.core.compiler.debug.sourceFile=generate +org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.autoboxing=ignore +org.eclipse.jdt.core.compiler.problem.deprecation=warning +org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled +org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled +org.eclipse.jdt.core.compiler.problem.discouragedReference=ignore +org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore +org.eclipse.jdt.core.compiler.problem.fieldHiding=ignore +org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning +org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning +org.eclipse.jdt.core.compiler.problem.forbiddenReference=error +org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning +org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning +org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=ignore +org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore +org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore +org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning +org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore +org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore +org.eclipse.jdt.core.compiler.problem.missingSerialVersion=ignore +org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning +org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning +org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore +org.eclipse.jdt.core.compiler.problem.nullReference=ignore +org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning +org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore +org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=ignore +org.eclipse.jdt.core.compiler.problem.rawTypeReference=ignore +org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled +org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning +org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled +org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore +org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning +org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning +org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore +org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning +org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore +org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=ignore +org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled +org.eclipse.jdt.core.compiler.problem.unusedImport=warning +org.eclipse.jdt.core.compiler.problem.unusedLabel=warning +org.eclipse.jdt.core.compiler.problem.unusedLocal=warning +org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore +org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled +org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled +org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning +org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning +org.eclipse.jdt.core.compiler.source=1.5 diff --git a/com.ibm.wala.eclipse/com.ibm.wala.eclipse/.settings/org.eclipse.jdt.ui.prefs b/com.ibm.wala.eclipse/com.ibm.wala.eclipse/.settings/org.eclipse.jdt.ui.prefs new file mode 100644 index 000000000..78efce42e --- /dev/null +++ b/com.ibm.wala.eclipse/com.ibm.wala.eclipse/.settings/org.eclipse.jdt.ui.prefs @@ -0,0 +1,3 @@ +#Tue Oct 10 11:07:11 EDT 2006 +eclipse.preferences.version=1 +internal.default.compliance=default diff --git a/com.ibm.wala.eclipse/com.ibm.wala.eclipse/META-INF/MANIFEST.MF b/com.ibm.wala.eclipse/com.ibm.wala.eclipse/META-INF/MANIFEST.MF new file mode 100644 index 000000000..eb32a744f --- /dev/null +++ b/com.ibm.wala.eclipse/com.ibm.wala.eclipse/META-INF/MANIFEST.MF @@ -0,0 +1,18 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Eclipse Plug-in +Bundle-SymbolicName: com.ibm.wala.eclipse;singleton:=true +Bundle-Version: 1.0.0 +Bundle-Activator: com.ibm.wala.eclipse.Activator +Bundle-Vendor: IBM +Bundle-Localization: plugin +Require-Bundle: org.eclipse.ui, + org.eclipse.core.runtime, + org.eclipse.core.resources, + org.eclipse.jdt.core, + org.eclipse.jdt.ui, + com.ibm.wala.core +Eclipse-LazyStart: true +Export-Package: com.ibm.wala.eclipse.cg.model, + com.ibm.wala.eclipse.cg.views, + com.ibm.wala.eclipse.util diff --git a/com.ibm.wala.eclipse/com.ibm.wala.eclipse/build.properties b/com.ibm.wala.eclipse/com.ibm.wala.eclipse/build.properties new file mode 100644 index 000000000..6f20375d6 --- /dev/null +++ b/com.ibm.wala.eclipse/com.ibm.wala.eclipse/build.properties @@ -0,0 +1,5 @@ +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + .,\ + plugin.xml diff --git a/com.ibm.wala.eclipse/com.ibm.wala.eclipse/build.xml b/com.ibm.wala.eclipse/com.ibm.wala.eclipse/build.xml new file mode 100644 index 000000000..385eaa143 --- /dev/null +++ b/com.ibm.wala.eclipse/com.ibm.wala.eclipse/build.xml @@ -0,0 +1,228 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/com.ibm.wala.eclipse/com.ibm.wala.eclipse/icons/Wala-icon.jpg b/com.ibm.wala.eclipse/com.ibm.wala.eclipse/icons/Wala-icon.jpg new file mode 100644 index 000000000..9c7f1d8b2 Binary files /dev/null and b/com.ibm.wala.eclipse/com.ibm.wala.eclipse/icons/Wala-icon.jpg differ diff --git a/com.ibm.wala.eclipse/com.ibm.wala.eclipse/javaCompiler...args b/com.ibm.wala.eclipse/com.ibm.wala.eclipse/javaCompiler...args new file mode 100644 index 000000000..783f6aaf9 --- /dev/null +++ b/com.ibm.wala.eclipse/com.ibm.wala.eclipse/javaCompiler...args @@ -0,0 +1,74 @@ +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.ui_3.2.0.I20060605-1400.jar[~org/eclipse/ui/internal/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.core.runtime_3.2.0.v20060603.jar[~org/eclipse/core/internal/preferences/legacy/*;~org/eclipse/core/internal/runtime/*;+org/eclipse/core/runtime/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.osgi_3.2.0.v20060601.jar[+org/eclipse/osgi/event/*;+org/eclipse/osgi/framework/console/*;+org/eclipse/osgi/framework/eventmgr/*;+org/eclipse/osgi/framework/log/*;+org/eclipse/osgi/service/datalocation/*;+org/eclipse/osgi/service/debug/*;+org/eclipse/osgi/service/environment/*;+org/eclipse/osgi/service/localization/*;+org/eclipse/osgi/service/pluginconversion/*;+org/eclipse/osgi/service/resolver/*;+org/eclipse/osgi/service/runnable/*;+org/eclipse/osgi/service/urlconversion/*;+org/eclipse/osgi/storagemanager/*;+org/eclipse/osgi/util/*;+org/osgi/framework/*;+org/osgi/service/condpermadmin/*;+org/osgi/service/packageadmin/*;+org/osgi/service/permissionadmin/*;+org/osgi/service/startlevel/*;+org/osgi/service/url/*;+org/osgi/util/tracker/*;~org/eclipse/core/runtime/adaptor/*;~org/eclipse/core/runtime/internal/adaptor/*;~org/eclipse/core/runtime/internal/stats/*;~org/eclipse/osgi/baseadaptor/*;~org/eclipse/osgi/baseadaptor/bundlefile/*;~org/eclipse/osgi/baseadaptor/hooks/*;~org/eclipse/osgi/baseadaptor/loader/*;~org/eclipse/osgi/framework/adaptor/*;~org/eclipse/osgi/framework/debug/*;~org/eclipse/osgi/framework/internal/core/*;~org/eclipse/osgi/framework/internal/protocol/*;~org/eclipse/osgi/framework/internal/protocol/bundleentry/*;~org/eclipse/osgi/framework/internal/protocol/bundleresource/*;~org/eclipse/osgi/framework/internal/protocol/reference/*;~org/eclipse/osgi/framework/internal/reliablefile/*;~org/eclipse/osgi/framework/launcher/*;~org/eclipse/osgi/framework/util/*;~org/eclipse/osgi/internal/baseadaptor/*;~org/eclipse/osgi/internal/module/*;~org/eclipse/osgi/internal/profile/*;~org/eclipse/osgi/internal/resolver/*;~org/eclipse/osgi/internal/verifier/*;~org/eclipse/osgi/internal/provisional/verifier/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.equinox.common_3.2.0.v20060603.jar[~org/eclipse/core/internal/runtime/*;~org/eclipse/core/internal/boot/*;+org/eclipse/core/runtime/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.core.jobs_3.2.0.v20060603.jar[~org/eclipse/core/internal/jobs/*;+org/eclipse/core/runtime/jobs/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.core.runtime.compatibility.registry_3.2.0.v20060603/runtime_registry_compatibility.jar[~org/eclipse/core/internal/registry/*;~org/eclipse/core/internal/registry/osgi/*;~org/eclipse/core/internal/registry/spi/*;+org/eclipse/core/runtime/*;+org/eclipse/core/runtime/dynamichelpers/*;+org/eclipse/core/runtime/spi/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.core.runtime.compatibility.registry_3.2.0.v20060603[~org/eclipse/core/internal/registry/*;~org/eclipse/core/internal/registry/osgi/*;~org/eclipse/core/internal/registry/spi/*;+org/eclipse/core/runtime/*;+org/eclipse/core/runtime/dynamichelpers/*;+org/eclipse/core/runtime/spi/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.equinox.registry_3.2.0.v20060601.jar[~org/eclipse/core/internal/registry/*;~org/eclipse/core/internal/registry/osgi/*;~org/eclipse/core/internal/registry/spi/*;+org/eclipse/core/runtime/*;+org/eclipse/core/runtime/dynamichelpers/*;+org/eclipse/core/runtime/spi/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.apache.xerces_2.8.0.v200606131651/resolver.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.apache.xerces_2.8.0.v200606131651/xercesImpl.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.apache.xerces_2.8.0.v200606131651/xml-apis.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.equinox.preferences_3.2.0.v20060601.jar[~org/eclipse/core/internal/preferences/*;~org/eclipse/core/internal/preferences/exchange/*;+org/eclipse/core/runtime/preferences/*;+org/osgi/service/prefs/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.core.runtime.compatibility.registry_3.2.0.v20060603/@dot[~org/eclipse/core/internal/registry/*;~org/eclipse/core/internal/registry/osgi/*;~org/eclipse/core/internal/registry/spi/*;+org/eclipse/core/runtime/*;+org/eclipse/core/runtime/dynamichelpers/*;+org/eclipse/core/runtime/spi/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.core.contenttype_3.2.0.v20060603.jar[~org/eclipse/core/internal/content/*;+org/eclipse/core/runtime/content/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.core.runtime.compatibility.auth_3.2.0.v20060601.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.swt_3.2.0.v3232o.jar[+org/eclipse/swt/*;+org/eclipse/swt/accessibility/*;+org/eclipse/swt/awt/*;+org/eclipse/swt/browser/*;+org/eclipse/swt/custom/*;+org/eclipse/swt/dnd/*;+org/eclipse/swt/events/*;+org/eclipse/swt/graphics/*;+org/eclipse/swt/layout/*;+org/eclipse/swt/opengl/*;+org/eclipse/swt/printing/*;+org/eclipse/swt/program/*;+org/eclipse/swt/widgets/*;~org/eclipse/swt/internal/*;~org/eclipse/swt/internal/image/*;~org/eclipse/swt/internal/theme/*;+org/eclipse/swt/ole/win32/*;~org/eclipse/swt/internal/gdip/*;~org/eclipse/swt/internal/ole/win32/*;~org/eclipse/swt/internal/win32/*;~org/eclipse/swt/internal/opengl/win32/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.swt.win32.win32.x86_3.2.0.v3232m.jar[+org/eclipse/swt/*;+org/eclipse/swt/accessibility/*;+org/eclipse/swt/awt/*;+org/eclipse/swt/browser/*;+org/eclipse/swt/custom/*;+org/eclipse/swt/dnd/*;+org/eclipse/swt/events/*;+org/eclipse/swt/graphics/*;+org/eclipse/swt/layout/*;+org/eclipse/swt/opengl/*;+org/eclipse/swt/printing/*;+org/eclipse/swt/program/*;+org/eclipse/swt/widgets/*;~org/eclipse/swt/internal/*;~org/eclipse/swt/internal/image/*;~org/eclipse/swt/internal/theme/*;+org/eclipse/swt/ole/win32/*;~org/eclipse/swt/internal/gdip/*;~org/eclipse/swt/internal/ole/win32/*;~org/eclipse/swt/internal/win32/*;~org/eclipse/swt/internal/opengl/win32/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.jface_3.2.0.I20060605-1400.jar[+org/eclipse/jface/*;+org/eclipse/jface/action/*;+org/eclipse/jface/action/images/*;+org/eclipse/jface/bindings/*;+org/eclipse/jface/bindings/keys/*;+org/eclipse/jface/bindings/keys/formatting/*;+org/eclipse/jface/commands/*;+org/eclipse/jface/contexts/*;+org/eclipse/jface/dialogs/*;+org/eclipse/jface/dialogs/images/*;+org/eclipse/jface/fieldassist/*;+org/eclipse/jface/fieldassist/images/*;+org/eclipse/jface/images/*;~org/eclipse/jface/internal/provisional/action/*;+org/eclipse/jface/layout/*;+org/eclipse/jface/menus/*;+org/eclipse/jface/operation/*;+org/eclipse/jface/preference/*;+org/eclipse/jface/preference/images/*;+org/eclipse/jface/resource/*;+org/eclipse/jface/util/*;+org/eclipse/jface/viewers/*;+org/eclipse/jface/viewers/deferred/*;+org/eclipse/jface/window/*;+org/eclipse/jface/wizard/*;+org/eclipse/jface/wizard/images/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.core.commands_3.2.0.I20060605-1400.jar[+org/eclipse/core/commands/*;+org/eclipse/core/commands/common/*;+org/eclipse/core/commands/contexts/*;+org/eclipse/core/commands/operations/*;+org/eclipse/core/commands/util/*;~org/eclipse/core/internal/commands/operations/*;~org/eclipse/core/internal/commands/util/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.ui.workbench_3.2.0.I20060605-1400.jar[+org/eclipse/ui/*;+org/eclipse/ui/about/*;+org/eclipse/ui/actions/*;+org/eclipse/ui/activities/*;+org/eclipse/ui/application/*;+org/eclipse/ui/branding/*;+org/eclipse/ui/browser/*;+org/eclipse/ui/commands/*;+org/eclipse/ui/contexts/*;+org/eclipse/ui/dialogs/*;+org/eclipse/ui/fieldassist/*;+org/eclipse/ui/handlers/*;+org/eclipse/ui/help/*;~org/eclipse/ui/internal/*;~org/eclipse/ui/internal/about/*;~org/eclipse/ui/internal/actions/*;~org/eclipse/ui/internal/activities/*;~org/eclipse/ui/internal/activities/ws/*;~org/eclipse/ui/internal/application/*;~org/eclipse/ui/internal/browser/*;~org/eclipse/ui/internal/commands/*;~org/eclipse/ui/internal/contexts/*;~org/eclipse/ui/internal/decorators/*;~org/eclipse/ui/internal/dialogs/*;~org/eclipse/ui/internal/dnd/*;~org/eclipse/ui/internal/editorsupport/*;~org/eclipse/ui/internal/expressions/*;~org/eclipse/ui/internal/handlers/*;~org/eclipse/ui/internal/help/*;~org/eclipse/ui/internal/intro/*;~org/eclipse/ui/internal/keys/*;~org/eclipse/ui/internal/layout/*;~org/eclipse/ui/internal/menus/*;~org/eclipse/ui/internal/misc/*;~org/eclipse/ui/internal/operations/*;~org/eclipse/ui/internal/part/*;~org/eclipse/ui/internal/preferences/*;~org/eclipse/ui/internal/presentations/*;~org/eclipse/ui/internal/presentations/defaultpresentation/*;~org/eclipse/ui/internal/presentations/util/*;~org/eclipse/ui/internal/progress/*;~org/eclipse/ui/internal/provisional/application/*;~org/eclipse/ui/internal/provisional/presentations/*;~org/eclipse/ui/internal/registry/*;~org/eclipse/ui/internal/services/*;~org/eclipse/ui/internal/testing/*;~org/eclipse/ui/internal/themes/*;~org/eclipse/ui/internal/util/*;~org/eclipse/ui/internal/wizards/*;~org/eclipse/ui/internal/wizards/preferences/*;+org/eclipse/ui/intro/*;+org/eclipse/ui/keys/*;+org/eclipse/ui/menus/*;+org/eclipse/ui/model/*;+org/eclipse/ui/operations/*;+org/eclipse/ui/part/*;+org/eclipse/ui/plugin/*;+org/eclipse/ui/preferences/*;+org/eclipse/ui/presentations/*;+org/eclipse/ui/progress/*;+org/eclipse/ui/services/*;+org/eclipse/ui/testing/*;+org/eclipse/ui/themes/*;+org/eclipse/ui/views/*;+org/eclipse/ui/wizards/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.ui.workbench.compatibility_3.2.0.I20060605-1400/@dot[+org/eclipse/ui/*;+org/eclipse/ui/about/*;+org/eclipse/ui/actions/*;+org/eclipse/ui/activities/*;+org/eclipse/ui/application/*;+org/eclipse/ui/branding/*;+org/eclipse/ui/browser/*;+org/eclipse/ui/commands/*;+org/eclipse/ui/contexts/*;+org/eclipse/ui/dialogs/*;+org/eclipse/ui/fieldassist/*;+org/eclipse/ui/handlers/*;+org/eclipse/ui/help/*;~org/eclipse/ui/internal/*;~org/eclipse/ui/internal/about/*;~org/eclipse/ui/internal/actions/*;~org/eclipse/ui/internal/activities/*;~org/eclipse/ui/internal/activities/ws/*;~org/eclipse/ui/internal/application/*;~org/eclipse/ui/internal/browser/*;~org/eclipse/ui/internal/commands/*;~org/eclipse/ui/internal/contexts/*;~org/eclipse/ui/internal/decorators/*;~org/eclipse/ui/internal/dialogs/*;~org/eclipse/ui/internal/dnd/*;~org/eclipse/ui/internal/editorsupport/*;~org/eclipse/ui/internal/expressions/*;~org/eclipse/ui/internal/handlers/*;~org/eclipse/ui/internal/help/*;~org/eclipse/ui/internal/intro/*;~org/eclipse/ui/internal/keys/*;~org/eclipse/ui/internal/layout/*;~org/eclipse/ui/internal/menus/*;~org/eclipse/ui/internal/misc/*;~org/eclipse/ui/internal/operations/*;~org/eclipse/ui/internal/part/*;~org/eclipse/ui/internal/preferences/*;~org/eclipse/ui/internal/presentations/*;~org/eclipse/ui/internal/presentations/defaultpresentation/*;~org/eclipse/ui/internal/presentations/util/*;~org/eclipse/ui/internal/progress/*;~org/eclipse/ui/internal/provisional/application/*;~org/eclipse/ui/internal/provisional/presentations/*;~org/eclipse/ui/internal/registry/*;~org/eclipse/ui/internal/services/*;~org/eclipse/ui/internal/testing/*;~org/eclipse/ui/internal/themes/*;~org/eclipse/ui/internal/util/*;~org/eclipse/ui/internal/wizards/*;~org/eclipse/ui/internal/wizards/preferences/*;+org/eclipse/ui/intro/*;+org/eclipse/ui/keys/*;+org/eclipse/ui/menus/*;+org/eclipse/ui/model/*;+org/eclipse/ui/operations/*;+org/eclipse/ui/part/*;+org/eclipse/ui/plugin/*;+org/eclipse/ui/preferences/*;+org/eclipse/ui/presentations/*;+org/eclipse/ui/progress/*;+org/eclipse/ui/services/*;+org/eclipse/ui/testing/*;+org/eclipse/ui/themes/*;+org/eclipse/ui/views/*;+org/eclipse/ui/wizards/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.ui.workbench.compatibility_3.2.0.I20060605-1400/compatibility.jar[+org/eclipse/ui/*;+org/eclipse/ui/about/*;+org/eclipse/ui/actions/*;+org/eclipse/ui/activities/*;+org/eclipse/ui/application/*;+org/eclipse/ui/branding/*;+org/eclipse/ui/browser/*;+org/eclipse/ui/commands/*;+org/eclipse/ui/contexts/*;+org/eclipse/ui/dialogs/*;+org/eclipse/ui/fieldassist/*;+org/eclipse/ui/handlers/*;+org/eclipse/ui/help/*;~org/eclipse/ui/internal/*;~org/eclipse/ui/internal/about/*;~org/eclipse/ui/internal/actions/*;~org/eclipse/ui/internal/activities/*;~org/eclipse/ui/internal/activities/ws/*;~org/eclipse/ui/internal/application/*;~org/eclipse/ui/internal/browser/*;~org/eclipse/ui/internal/commands/*;~org/eclipse/ui/internal/contexts/*;~org/eclipse/ui/internal/decorators/*;~org/eclipse/ui/internal/dialogs/*;~org/eclipse/ui/internal/dnd/*;~org/eclipse/ui/internal/editorsupport/*;~org/eclipse/ui/internal/expressions/*;~org/eclipse/ui/internal/handlers/*;~org/eclipse/ui/internal/help/*;~org/eclipse/ui/internal/intro/*;~org/eclipse/ui/internal/keys/*;~org/eclipse/ui/internal/layout/*;~org/eclipse/ui/internal/menus/*;~org/eclipse/ui/internal/misc/*;~org/eclipse/ui/internal/operations/*;~org/eclipse/ui/internal/part/*;~org/eclipse/ui/internal/preferences/*;~org/eclipse/ui/internal/presentations/*;~org/eclipse/ui/internal/presentations/defaultpresentation/*;~org/eclipse/ui/internal/presentations/util/*;~org/eclipse/ui/internal/progress/*;~org/eclipse/ui/internal/provisional/application/*;~org/eclipse/ui/internal/provisional/presentations/*;~org/eclipse/ui/internal/registry/*;~org/eclipse/ui/internal/services/*;~org/eclipse/ui/internal/testing/*;~org/eclipse/ui/internal/themes/*;~org/eclipse/ui/internal/util/*;~org/eclipse/ui/internal/wizards/*;~org/eclipse/ui/internal/wizards/preferences/*;+org/eclipse/ui/intro/*;+org/eclipse/ui/keys/*;+org/eclipse/ui/menus/*;+org/eclipse/ui/model/*;+org/eclipse/ui/operations/*;+org/eclipse/ui/part/*;+org/eclipse/ui/plugin/*;+org/eclipse/ui/preferences/*;+org/eclipse/ui/presentations/*;+org/eclipse/ui/progress/*;+org/eclipse/ui/services/*;+org/eclipse/ui/testing/*;+org/eclipse/ui/themes/*;+org/eclipse/ui/views/*;+org/eclipse/ui/wizards/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/com.ibm.icu_3.4.4.1.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.help_3.2.0.v20060602.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.core.expressions_3.2.0.v20060605-1400.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.core.resources_3.2.0.v20060603.jar[~org/eclipse/core/internal/dtree/*;~org/eclipse/core/internal/events/*;~org/eclipse/core/internal/localstore/*;~org/eclipse/core/internal/properties/*;~org/eclipse/core/internal/propertytester/*;~org/eclipse/core/internal/refresh/*;~org/eclipse/core/internal/resources/*;~org/eclipse/core/internal/resources/mapping/*;~org/eclipse/core/internal/utils/*;~org/eclipse/core/internal/watson/*;+org/eclipse/core/resources/*;+org/eclipse/core/resources/mapping/*;+org/eclipse/core/resources/refresh/*;+org/eclipse/core/resources/team/*;~org/eclipse/core/internal/indexing/*;~org/eclipse/core/internal/resources/refresh/win32/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.core.resources.compatibility_3.2.0.v20060603.jar[~org/eclipse/core/internal/dtree/*;~org/eclipse/core/internal/events/*;~org/eclipse/core/internal/localstore/*;~org/eclipse/core/internal/properties/*;~org/eclipse/core/internal/propertytester/*;~org/eclipse/core/internal/refresh/*;~org/eclipse/core/internal/resources/*;~org/eclipse/core/internal/resources/mapping/*;~org/eclipse/core/internal/utils/*;~org/eclipse/core/internal/watson/*;+org/eclipse/core/resources/*;+org/eclipse/core/resources/mapping/*;+org/eclipse/core/resources/refresh/*;+org/eclipse/core/resources/team/*;~org/eclipse/core/internal/indexing/*;~org/eclipse/core/internal/resources/refresh/win32/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.core.resources.win32_3.2.0.v20060603.jar[~org/eclipse/core/internal/dtree/*;~org/eclipse/core/internal/events/*;~org/eclipse/core/internal/localstore/*;~org/eclipse/core/internal/properties/*;~org/eclipse/core/internal/propertytester/*;~org/eclipse/core/internal/refresh/*;~org/eclipse/core/internal/resources/*;~org/eclipse/core/internal/resources/mapping/*;~org/eclipse/core/internal/utils/*;~org/eclipse/core/internal/watson/*;+org/eclipse/core/resources/*;+org/eclipse/core/resources/mapping/*;+org/eclipse/core/resources/refresh/*;+org/eclipse/core/resources/team/*;~org/eclipse/core/internal/indexing/*;~org/eclipse/core/internal/resources/refresh/win32/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.core.runtime.compatibility_3.1.100.v20060603.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.update.configurator_3.2.0.v20060605.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.ant.core_3.1.100.v20060531.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.core.variables_3.1.100.v20060605.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.core.filesystem_1.0.0.v20060603.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.core.filesystem.win32.x86_1.0.0.v20060603.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.jdt.core_3.2.0.v_671.jar[+org/eclipse/jdt/core/*;+org/eclipse/jdt/core/compiler/*;+org/eclipse/jdt/core/dom/*;+org/eclipse/jdt/core/dom/rewrite/*;+org/eclipse/jdt/core/eval/*;+org/eclipse/jdt/core/formatter/*;+org/eclipse/jdt/core/jdom/*;+org/eclipse/jdt/core/search/*;+org/eclipse/jdt/core/util/*;~org/eclipse/jdt/internal/codeassist/*;~org/eclipse/jdt/internal/codeassist/complete/*;~org/eclipse/jdt/internal/codeassist/impl/*;~org/eclipse/jdt/internal/codeassist/select/*;~org/eclipse/jdt/internal/compiler/*;~org/eclipse/jdt/internal/compiler/ast/*;~org/eclipse/jdt/internal/compiler/batch/*;~org/eclipse/jdt/internal/compiler/classfmt/*;~org/eclipse/jdt/internal/compiler/codegen/*;~org/eclipse/jdt/internal/compiler/env/*;~org/eclipse/jdt/internal/compiler/flow/*;~org/eclipse/jdt/internal/compiler/impl/*;~org/eclipse/jdt/internal/compiler/lookup/*;~org/eclipse/jdt/internal/compiler/parser/*;~org/eclipse/jdt/internal/compiler/parser/diagnose/*;~org/eclipse/jdt/internal/compiler/problem/*;~org/eclipse/jdt/internal/compiler/util/*;~org/eclipse/jdt/internal/core/*;~org/eclipse/jdt/internal/core/builder/*;~org/eclipse/jdt/internal/core/dom/rewrite/*;~org/eclipse/jdt/internal/core/eval/*;~org/eclipse/jdt/internal/core/hierarchy/*;~org/eclipse/jdt/internal/core/index/*;~org/eclipse/jdt/internal/core/jdom/*;~org/eclipse/jdt/internal/core/search/*;~org/eclipse/jdt/internal/core/search/indexing/*;~org/eclipse/jdt/internal/core/search/matching/*;~org/eclipse/jdt/internal/core/search/processing/*;~org/eclipse/jdt/internal/core/util/*;~org/eclipse/jdt/internal/eval/*;~org/eclipse/jdt/internal/formatter/*;~org/eclipse/jdt/internal/formatter/align/*;~org/eclipse/jdt/internal/formatter/comment/*;~org/eclipse/jdt/internal/formatter/old/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.text_3.2.0.v20060605-1400.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.team.core_3.2.0.I200606051140.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.jdt.ui_3.2.0.v20060605-1400.jar[~org/eclipse/jdt/internal/corext/*;~org/eclipse/jdt/internal/corext/buildpath/*;~org/eclipse/jdt/internal/corext/callhierarchy/*;~org/eclipse/jdt/internal/corext/codemanipulation/*;~org/eclipse/jdt/internal/corext/dom/*;~org/eclipse/jdt/internal/corext/dom/fragments/*;~org/eclipse/jdt/internal/corext/fix/*;~org/eclipse/jdt/internal/corext/javadoc/*;~org/eclipse/jdt/internal/corext/refactoring/*;~org/eclipse/jdt/internal/corext/refactoring/base/*;~org/eclipse/jdt/internal/corext/refactoring/binary/*;~org/eclipse/jdt/internal/corext/refactoring/changes/*;~org/eclipse/jdt/internal/corext/refactoring/code/*;~org/eclipse/jdt/internal/corext/refactoring/code/flow/*;~org/eclipse/jdt/internal/corext/refactoring/delegates/*;~org/eclipse/jdt/internal/corext/refactoring/generics/*;~org/eclipse/jdt/internal/corext/refactoring/nls/*;~org/eclipse/jdt/internal/corext/refactoring/nls/changes/*;~org/eclipse/jdt/internal/corext/refactoring/participants/*;~org/eclipse/jdt/internal/corext/refactoring/rename/*;~org/eclipse/jdt/internal/corext/refactoring/reorg/*;~org/eclipse/jdt/internal/corext/refactoring/scripting/*;~org/eclipse/jdt/internal/corext/refactoring/sef/*;~org/eclipse/jdt/internal/corext/refactoring/structure/*;~org/eclipse/jdt/internal/corext/refactoring/structure/constraints/*;~org/eclipse/jdt/internal/corext/refactoring/surround/*;~org/eclipse/jdt/internal/corext/refactoring/tagging/*;~org/eclipse/jdt/internal/corext/refactoring/typeconstraints/*;~org/eclipse/jdt/internal/corext/refactoring/typeconstraints/types/*;~org/eclipse/jdt/internal/corext/refactoring/typeconstraints/typesets/*;~org/eclipse/jdt/internal/corext/refactoring/typeconstraints2/*;~org/eclipse/jdt/internal/corext/refactoring/util/*;~org/eclipse/jdt/internal/corext/template/java/*;~org/eclipse/jdt/internal/corext/util/*;~org/eclipse/jdt/internal/ui/*;~org/eclipse/jdt/internal/ui/actions/*;~org/eclipse/jdt/internal/ui/browsing/*;~org/eclipse/jdt/internal/ui/callhierarchy/*;~org/eclipse/jdt/internal/ui/commands/*;~org/eclipse/jdt/internal/ui/compare/*;~org/eclipse/jdt/internal/ui/dialogs/*;~org/eclipse/jdt/internal/ui/dnd/*;~org/eclipse/jdt/internal/ui/filters/*;~org/eclipse/jdt/internal/ui/fix/*;~org/eclipse/jdt/internal/ui/infoviews/*;~org/eclipse/jdt/internal/ui/jarimport/*;~org/eclipse/jdt/internal/ui/jarpackager/*;~org/eclipse/jdt/internal/ui/javadocexport/*;~org/eclipse/jdt/internal/ui/javaeditor/*;~org/eclipse/jdt/internal/ui/javaeditor/selectionactions/*;~org/eclipse/jdt/internal/ui/model/*;~org/eclipse/jdt/internal/ui/navigator/*;~org/eclipse/jdt/internal/ui/packageview/*;~org/eclipse/jdt/internal/ui/preferences/*;~org/eclipse/jdt/internal/ui/preferences/formatter/*;~org/eclipse/jdt/internal/ui/propertiesfileeditor/*;~org/eclipse/jdt/internal/ui/refactoring/*;~org/eclipse/jdt/internal/ui/refactoring/actions/*;~org/eclipse/jdt/internal/ui/refactoring/binary/*;~org/eclipse/jdt/internal/ui/refactoring/code/*;~org/eclipse/jdt/internal/ui/refactoring/contentassist/*;~org/eclipse/jdt/internal/ui/refactoring/nls/*;~org/eclipse/jdt/internal/ui/refactoring/nls/search/*;~org/eclipse/jdt/internal/ui/refactoring/reorg/*;~org/eclipse/jdt/internal/ui/refactoring/sef/*;~org/eclipse/jdt/internal/ui/search/*;~org/eclipse/jdt/internal/ui/text/*;~org/eclipse/jdt/internal/ui/text/comment/*;~org/eclipse/jdt/internal/ui/text/correction/*;~org/eclipse/jdt/internal/ui/text/folding/*;~org/eclipse/jdt/internal/ui/text/java/*;~org/eclipse/jdt/internal/ui/text/java/hover/*;~org/eclipse/jdt/internal/ui/text/javadoc/*;~org/eclipse/jdt/internal/ui/text/spelling/*;~org/eclipse/jdt/internal/ui/text/spelling/engine/*;~org/eclipse/jdt/internal/ui/text/template/contentassist/*;~org/eclipse/jdt/internal/ui/text/template/preferences/*;~org/eclipse/jdt/internal/ui/typehierarchy/*;~org/eclipse/jdt/internal/ui/util/*;~org/eclipse/jdt/internal/ui/viewsupport/*;~org/eclipse/jdt/internal/ui/wizards/*;~org/eclipse/jdt/internal/ui/wizards/buildpaths/*;~org/eclipse/jdt/internal/ui/wizards/buildpaths/newsourcepage/*;~org/eclipse/jdt/internal/ui/wizards/dialogfields/*;~org/eclipse/jdt/internal/ui/workingsets/*;+org/eclipse/jdt/ui/*;+org/eclipse/jdt/ui/actions/*;+org/eclipse/jdt/ui/dialogs/*;+org/eclipse/jdt/ui/jarpackager/*;+org/eclipse/jdt/ui/refactoring/*;+org/eclipse/jdt/ui/search/*;+org/eclipse/jdt/ui/text/*;+org/eclipse/jdt/ui/text/folding/*;+org/eclipse/jdt/ui/text/java/*;+org/eclipse/jdt/ui/text/java/hover/*;+org/eclipse/jdt/ui/wizards/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.ui.console_3.1.100.v20060605.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.jface.text_3.2.0.v20060605-1400.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.ui.workbench.texteditor_3.2.0.v20060605-1400.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.search_3.2.0.v20060605-1400.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.core.filebuffers_3.2.0.v20060605-1400.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.ui.ide_3.2.0.I20060605-1400.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.ui.win32_3.2.0.I20060605-1400.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.ui.views_3.2.0.I20060605-1400.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.update.core_3.2.0.v20060605.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.update.core.win32_3.2.0.v20060605.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.update.ui_3.2.0.v20060605.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.ui.forms_3.2.0.v20060602.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.debug.core_3.2.0.v20060605.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.debug.ui_3.2.0.v20060605.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.ui.editors_3.2.0.v20060605-1400.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.jdt.launching_3.2.0.v20060605.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.jdt.debug_3.2.0.v20060605/jdi.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.jdt.debug_3.2.0.v20060605/jdimodel.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.jdt.debug_3.2.0.v20060605/tools.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.compare_3.2.0.v20060605.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.team.ui_3.2.0.I200606051140.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.ui.navigator_3.2.0.I20060605-1400.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.ui.navigator.resources_3.2.0.I20060605-1400.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.ui.views.properties.tabbed_3.2.0.I20060605-1400.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.ltk.core.refactoring_3.2.0.v20060605-1400.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.ltk.ui.refactoring_3.2.0.v20060605-1400.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.jdt.core.manipulation_1.0.0.v20060605-1400.jar[?**/*] +#ADAPTER#ACCESS#com.ibm.wala.core/bin/[+com/ibm/wala/analysis/pointers/*;+com/ibm/wala/analysis/reflection/*;+com/ibm/wala/analysis/stackMachine/*;+com/ibm/wala/analysis/typeInference/*;+com/ibm/wala/cfg/*;+com/ibm/wala/cfg/cdg/*;+com/ibm/wala/classLoader/*;+com/ibm/wala/client/*;+com/ibm/wala/client/impl/*;+com/ibm/wala/core/plugin/*;+com/ibm/wala/dataflow/IFDS/*;+com/ibm/wala/dataflow/graph/*;+com/ibm/wala/dataflow/ssa/*;+com/ibm/wala/dynamic/*;+com/ibm/wala/emf/wrappers/*;+com/ibm/wala/escape/*;+com/ibm/wala/fixedpoint/impl/*;+com/ibm/wala/fixpoint/*;+com/ibm/wala/ipa/callgraph/*;+com/ibm/wala/ipa/callgraph/impl/*;+com/ibm/wala/ipa/callgraph/propagation/*;+com/ibm/wala/ipa/callgraph/propagation/cfa/*;+com/ibm/wala/ipa/callgraph/propagation/rta/*;+com/ibm/wala/ipa/cfg/*;+com/ibm/wala/ipa/cha/*;+com/ibm/wala/ipa/summaries/*;+com/ibm/wala/model/*;+com/ibm/wala/model/java/lang/*;+com/ibm/wala/properties/*;+com/ibm/wala/ssa/*;+com/ibm/wala/ssa/analysis/*;+com/ibm/wala/types/*;+com/ibm/wala/util/*;+com/ibm/wala/util/bytecode/*;+com/ibm/wala/util/collections/*;+com/ibm/wala/util/config/*;+com/ibm/wala/util/debug/*;+com/ibm/wala/util/graph/*;+com/ibm/wala/util/graph/impl/*;+com/ibm/wala/util/graph/traverse/*;+com/ibm/wala/util/heapTrace/*;+com/ibm/wala/util/intertionalization/*;+com/ibm/wala/util/intset/*;+com/ibm/wala/util/io/*;+com/ibm/wala/util/logging/*;+com/ibm/wala/util/math/*;+com/ibm/wala/util/perf/*;+com/ibm/wala/util/system/*;+com/ibm/wala/util/warnings/*;+com/ibm/wala/viz/*;?**/*] +#ADAPTER#ACCESS#com.ibm.wala.core/@dot[+com/ibm/wala/analysis/pointers/*;+com/ibm/wala/analysis/reflection/*;+com/ibm/wala/analysis/stackMachine/*;+com/ibm/wala/analysis/typeInference/*;+com/ibm/wala/cfg/*;+com/ibm/wala/cfg/cdg/*;+com/ibm/wala/classLoader/*;+com/ibm/wala/client/*;+com/ibm/wala/client/impl/*;+com/ibm/wala/core/plugin/*;+com/ibm/wala/dataflow/IFDS/*;+com/ibm/wala/dataflow/graph/*;+com/ibm/wala/dataflow/ssa/*;+com/ibm/wala/dynamic/*;+com/ibm/wala/emf/wrappers/*;+com/ibm/wala/escape/*;+com/ibm/wala/fixedpoint/impl/*;+com/ibm/wala/fixpoint/*;+com/ibm/wala/ipa/callgraph/*;+com/ibm/wala/ipa/callgraph/impl/*;+com/ibm/wala/ipa/callgraph/propagation/*;+com/ibm/wala/ipa/callgraph/propagation/cfa/*;+com/ibm/wala/ipa/callgraph/propagation/rta/*;+com/ibm/wala/ipa/cfg/*;+com/ibm/wala/ipa/cha/*;+com/ibm/wala/ipa/summaries/*;+com/ibm/wala/model/*;+com/ibm/wala/model/java/lang/*;+com/ibm/wala/properties/*;+com/ibm/wala/ssa/*;+com/ibm/wala/ssa/analysis/*;+com/ibm/wala/types/*;+com/ibm/wala/util/*;+com/ibm/wala/util/bytecode/*;+com/ibm/wala/util/collections/*;+com/ibm/wala/util/config/*;+com/ibm/wala/util/debug/*;+com/ibm/wala/util/graph/*;+com/ibm/wala/util/graph/impl/*;+com/ibm/wala/util/graph/traverse/*;+com/ibm/wala/util/heapTrace/*;+com/ibm/wala/util/intertionalization/*;+com/ibm/wala/util/intset/*;+com/ibm/wala/util/io/*;+com/ibm/wala/util/logging/*;+com/ibm/wala/util/math/*;+com/ibm/wala/util/perf/*;+com/ibm/wala/util/system/*;+com/ibm/wala/util/warnings/*;+com/ibm/wala/viz/*;?**/*] +#ADAPTER#ACCESS#com.ibm.wala.emf/bin/[+com/ibm/wala/ecore/common/*;+com/ibm/wala/ecore/common/impl/*;+com/ibm/wala/ecore/common/util/*;+com/ibm/wala/ecore/graph/*;+com/ibm/wala/ecore/graph/impl/*;+com/ibm/wala/ecore/graph/util/*;+com/ibm/wala/ecore/j2ee/scope/*;+com/ibm/wala/ecore/j2ee/scope/impl/*;+com/ibm/wala/ecore/j2ee/scope/util/*;+com/ibm/wala/ecore/java/*;+com/ibm/wala/ecore/java/callGraph/*;+com/ibm/wala/ecore/java/callGraph/impl/*;+com/ibm/wala/ecore/java/callGraph/util/*;+com/ibm/wala/ecore/java/impl/*;+com/ibm/wala/ecore/java/pointerAnalysis/*;+com/ibm/wala/ecore/java/pointerAnalysis/impl/*;+com/ibm/wala/ecore/java/pointerAnalysis/util/*;+com/ibm/wala/ecore/java/scope/*;+com/ibm/wala/ecore/java/scope/impl/*;+com/ibm/wala/ecore/java/scope/util/*;+com/ibm/wala/ecore/java/util/*;+com/ibm/wala/ecore/perf/*;+com/ibm/wala/ecore/perf/impl/*;+com/ibm/wala/ecore/perf/util/*;+com/ibm/wala/ecore/regex/*;+com/ibm/wala/ecore/regex/impl/*;+com/ibm/wala/ecore/regex/util/*;?**/*] +#ADAPTER#ACCESS#com.ibm.wala.emf/@dot[+com/ibm/wala/ecore/common/*;+com/ibm/wala/ecore/common/impl/*;+com/ibm/wala/ecore/common/util/*;+com/ibm/wala/ecore/graph/*;+com/ibm/wala/ecore/graph/impl/*;+com/ibm/wala/ecore/graph/util/*;+com/ibm/wala/ecore/j2ee/scope/*;+com/ibm/wala/ecore/j2ee/scope/impl/*;+com/ibm/wala/ecore/j2ee/scope/util/*;+com/ibm/wala/ecore/java/*;+com/ibm/wala/ecore/java/callGraph/*;+com/ibm/wala/ecore/java/callGraph/impl/*;+com/ibm/wala/ecore/java/callGraph/util/*;+com/ibm/wala/ecore/java/impl/*;+com/ibm/wala/ecore/java/pointerAnalysis/*;+com/ibm/wala/ecore/java/pointerAnalysis/impl/*;+com/ibm/wala/ecore/java/pointerAnalysis/util/*;+com/ibm/wala/ecore/java/scope/*;+com/ibm/wala/ecore/java/scope/impl/*;+com/ibm/wala/ecore/java/scope/util/*;+com/ibm/wala/ecore/java/util/*;+com/ibm/wala/ecore/perf/*;+com/ibm/wala/ecore/perf/impl/*;+com/ibm/wala/ecore/perf/util/*;+com/ibm/wala/ecore/regex/*;+com/ibm/wala/ecore/regex/impl/*;+com/ibm/wala/ecore/regex/util/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.emf.ecore_2.2.0.v200606271057.jar[+org/eclipse/emf/ecore/*;+org/eclipse/emf/ecore/impl/*;+org/eclipse/emf/ecore/plugin/*;+org/eclipse/emf/ecore/resource/*;+org/eclipse/emf/ecore/resource/impl/*;+org/eclipse/emf/ecore/util/*;+org/eclipse/emf/ecore/xml/namespace/*;+org/eclipse/emf/ecore/xml/namespace/impl/*;+org/eclipse/emf/ecore/xml/namespace/util/*;+org/eclipse/emf/ecore/xml/type/*;+org/eclipse/emf/ecore/xml/type/impl/*;+org/eclipse/emf/ecore/xml/type/internal/*;+org/eclipse/emf/ecore/xml/type/util/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.emf.common_2.2.0.v200606271057.jar[+org/eclipse/emf/common/*;+org/eclipse/emf/common/archive/*;+org/eclipse/emf/common/command/*;+org/eclipse/emf/common/notify/*;+org/eclipse/emf/common/notify/impl/*;+org/eclipse/emf/common/util/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.emf.ecore.xmi_2.2.0.v200606271057.jar[+org/eclipse/emf/ecore/xmi/*;+org/eclipse/emf/ecore/xmi/impl/*;+org/eclipse/emf/ecore/xmi/util/*;?**/*] +#ADAPTER#ACCESS#com.ibm.wala.shrike/bin/[+com/ibm/wala/shrike/bench/*;+com/ibm/wala/shrike/copywriter/*;+com/ibm/wala/shrike/tools/*;+com/ibm/wala/shrikeBT/*;+com/ibm/wala/shrikeBT/analysis/*;+com/ibm/wala/shrikeBT/info/*;+com/ibm/wala/shrikeBT/shrikeCT/*;+com/ibm/wala/shrikeBT/shrikeCT/tools/*;+com/ibm/wala/shrikeBT/tools/*;+com/ibm/wala/shrikeCT/*;?**/*] +#ADAPTER#ACCESS#com.ibm.wala.shrike/@dot[+com/ibm/wala/shrike/bench/*;+com/ibm/wala/shrike/copywriter/*;+com/ibm/wala/shrike/tools/*;+com/ibm/wala/shrikeBT/*;+com/ibm/wala/shrikeBT/analysis/*;+com/ibm/wala/shrikeBT/info/*;+com/ibm/wala/shrikeBT/shrikeCT/*;+com/ibm/wala/shrikeBT/shrikeCT/tools/*;+com/ibm/wala/shrikeBT/tools/*;+com/ibm/wala/shrikeCT/*;?**/*] diff --git a/com.ibm.wala.eclipse/com.ibm.wala.eclipse/launchers/wala.eclipse.launch b/com.ibm.wala.eclipse/com.ibm.wala.eclipse/launchers/wala.eclipse.launch new file mode 100644 index 000000000..a74fe9ccf --- /dev/null +++ b/com.ibm.wala.eclipse/com.ibm.wala.eclipse/launchers/wala.eclipse.launch @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/com.ibm.wala.eclipse/com.ibm.wala.eclipse/plugin.xml b/com.ibm.wala.eclipse/com.ibm.wala.eclipse/plugin.xml new file mode 100644 index 000000000..ad6ec0734 --- /dev/null +++ b/com.ibm.wala.eclipse/com.ibm.wala.eclipse/plugin.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + diff --git a/com.ibm.wala.eclipse/com.ibm.wala.eclipse/src/com/ibm/wala/eclipse/Activator.java b/com.ibm.wala.eclipse/com.ibm.wala.eclipse/src/com/ibm/wala/eclipse/Activator.java new file mode 100644 index 000000000..3f858a2d4 --- /dev/null +++ b/com.ibm.wala.eclipse/com.ibm.wala.eclipse/src/com/ibm/wala/eclipse/Activator.java @@ -0,0 +1,60 @@ +/******************************************************************************* + * 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.eclipse; + +import org.eclipse.ui.plugin.AbstractUIPlugin; +import org.osgi.framework.BundleContext; + +/** + * The activator class controls the plug-in life cycle + */ +public class Activator extends AbstractUIPlugin { + + // The plug-in ID + public static final String PLUGIN_ID = "com.ibm.wala.eclipse"; + + // The shared instance + private static Activator plugin; + + /** + * The constructor + */ + public Activator() { + plugin = this; + } + + /* + * (non-Javadoc) + * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext) + */ + public void start(BundleContext context) throws Exception { + super.start(context); + } + + /* + * (non-Javadoc) + * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext) + */ + public void stop(BundleContext context) throws Exception { + plugin = null; + super.stop(context); + } + + /** + * Returns the shared instance + * + * @return the shared instance + */ + public static Activator getDefault() { + return plugin; + } + +} diff --git a/com.ibm.wala.eclipse/com.ibm.wala.eclipse/src/com/ibm/wala/eclipse/cg/model/WalaCGModel.java b/com.ibm.wala.eclipse/com.ibm.wala.eclipse/src/com/ibm/wala/eclipse/cg/model/WalaCGModel.java new file mode 100644 index 000000000..93f8f200b --- /dev/null +++ b/com.ibm.wala.eclipse/com.ibm.wala.eclipse/src/com/ibm/wala/eclipse/cg/model/WalaCGModel.java @@ -0,0 +1,86 @@ +/******************************************************************************* + * 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.eclipse.cg.model; + +import java.util.Collection; + +import org.eclipse.jface.window.ApplicationWindow; + +import com.ibm.wala.ecore.java.scope.EJavaAnalysisScope; +import com.ibm.wala.emf.wrappers.EMFScopeWrapper; +import com.ibm.wala.emf.wrappers.JavaScopeUtil; +import com.ibm.wala.ipa.callgraph.CallGraph; +import com.ibm.wala.util.graph.Graph; +import com.ibm.wala.util.warnings.WalaException; +import com.ibm.wala.viz.SWTTreeViewer; + + +abstract public class WalaCGModel { + + /** + * Specifies the path of the jars files to be analyzed, each jar file separated by ';' + */ + protected String appJar; + + protected CallGraph callGraph; + + protected Collection roots; + + /** + * @param appJar Specifies the path of the jars files to be analyzed, each jar file separated by ';' + */ + public WalaCGModel(String appJar) { + this.appJar = appJar; + } + + /** + * @see CallGraphBuilderImpl.processImpl + * warning: this is bypassing emf and may cause problems + */ + public void buildGraph() throws WalaException { + EMFScopeWrapper escope = createAnalysisScope(); + callGraph = createCallGraph(escope); + roots = inferRoots(callGraph); + } + + public Graph getGraph() { + return callGraph; + } + + public Collection getRoots() { + return roots; + } + + /** + * @see SWTCallGraph + */ + protected EMFScopeWrapper createAnalysisScope() throws WalaException { + EJavaAnalysisScope escope = JavaScopeUtil.makeAnalysisScope(appJar); + + escope.setExclusionFileName("J2SEClassHierarchyExclusions.xml"); + + // generate a DOMO-consumable wrapper around the incoming scope object + EMFScopeWrapper scope = EMFScopeWrapper.generateScope(escope); + return scope; + } + + abstract protected CallGraph createCallGraph(EMFScopeWrapper escope) throws WalaException; + + abstract protected Collection inferRoots(CallGraph cg) throws WalaException; + + public ApplicationWindow makeUI(Graph graph, Collection roots) throws WalaException { + final SWTTreeViewer v = new SWTTreeViewer(); + v.setGraphInput(graph); + v.setRootsInput(roots); + v.run(); + return v.getApplicationWindow(); + } +} diff --git a/com.ibm.wala.eclipse/com.ibm.wala.eclipse/src/com/ibm/wala/eclipse/cg/model/WalaCGModelWithMain.java b/com.ibm.wala.eclipse/com.ibm.wala.eclipse/src/com/ibm/wala/eclipse/cg/model/WalaCGModelWithMain.java new file mode 100644 index 000000000..c71432d00 --- /dev/null +++ b/com.ibm.wala.eclipse/com.ibm.wala.eclipse/src/com/ibm/wala/eclipse/cg/model/WalaCGModelWithMain.java @@ -0,0 +1,67 @@ +/******************************************************************************* + * 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.eclipse.cg.model; + +import java.util.Collection; + +import com.ibm.wala.emf.wrappers.EMFScopeWrapper; +import com.ibm.wala.ipa.callgraph.AnalysisOptions; +import com.ibm.wala.ipa.callgraph.CallGraph; +import com.ibm.wala.ipa.callgraph.Entrypoints; +import com.ibm.wala.ipa.callgraph.impl.Util; +import com.ibm.wala.ipa.cha.ClassHierarchy; +import com.ibm.wala.util.graph.InferGraphRootsImpl; +import com.ibm.wala.util.warnings.WalaException; +import com.ibm.wala.util.warnings.WarningSet; + +/** + * + * @author aying + */ +public class WalaCGModelWithMain extends WalaCGModel { + + /* + * @see WalaCGModel + */ + public WalaCGModelWithMain(String appJar) { + super(appJar); + } + + /** + * @see SWTCallGraph + */ + @Override + protected CallGraph createCallGraph(EMFScopeWrapper scope) throws WalaException { + + // TODO: return the warning set (need a CAPA type) + // invoke DOMO to build a DOMO class hierarchy object + WarningSet warnings = new WarningSet(); + ClassHierarchy cha = ClassHierarchy.make(scope, warnings); + + Entrypoints entrypoints = com.ibm.wala.ipa.callgraph.impl.Util.makeMainEntrypoints(scope, cha); + AnalysisOptions options = new AnalysisOptions(scope, entrypoints); + + // // + // build the call graph + // // + com.ibm.wala.ipa.callgraph.CallGraphBuilder builder = Util.makeZeroCFABuilder(options, cha, scope, warnings, null, null); + CallGraph cg = builder.makeCallGraph(options); + return cg; + } + + /** + * @see SWTCallGraph + */ + @Override + protected Collection inferRoots(CallGraph cg) throws WalaException { + return InferGraphRootsImpl.inferRoots(cg); + } +} diff --git a/com.ibm.wala.eclipse/com.ibm.wala.eclipse/src/com/ibm/wala/eclipse/cg/views/CGContentProvider.java b/com.ibm.wala.eclipse/com.ibm.wala.eclipse/src/com/ibm/wala/eclipse/cg/views/CGContentProvider.java new file mode 100644 index 000000000..9f12407ea --- /dev/null +++ b/com.ibm.wala.eclipse/com.ibm.wala.eclipse/src/com/ibm/wala/eclipse/cg/views/CGContentProvider.java @@ -0,0 +1,117 @@ +/******************************************************************************* + * 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.eclipse.cg.views; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.Map; + +import org.eclipse.jdt.core.IJavaElement; +import org.eclipse.jface.viewers.ITreeContentProvider; +import org.eclipse.jface.viewers.Viewer; + +import com.ibm.wala.ipa.callgraph.CGNode; +import com.ibm.wala.util.debug.Assertions; +import com.ibm.wala.util.graph.Graph; + +/** + * @author sfink + * @author aying + * + * Simple wrapper around an EObjectGraph to provide content for a tree viewer. + */ +public class CGContentProvider implements ITreeContentProvider { + + protected Graph graph; + + protected Collection roots; + + protected Map capaNodeIdToJavaElement = null; + + public CGContentProvider(Graph g, Collection roots, Map capaNodeIdToJavaElement) { + this.graph = g; + this.roots = roots; + this.capaNodeIdToJavaElement = capaNodeIdToJavaElement; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.viewers.IContentProvider#dispose() + */ + public void dispose() { + // do nothing for now + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.viewers.IContentProvider#inputChanged(org.eclipse.jface.viewers.Viewer, + * java.lang.Object, java.lang.Object) + */ + public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { + // for now do nothing, since we're not dealing with listeners + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.viewers.ITreeContentProvider#getChildren(java.lang.Object) + */ + public Object[] getChildren(Object parentElement) { + + Collection result = new ArrayList(); + for (Iterator it = graph.getSuccNodes((CGNode) parentElement); it.hasNext();) { + CGNode capaNode = (CGNode) it.next(); + result.add(capaNode); + } + return result.toArray(); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.viewers.ITreeContentProvider#getParent(java.lang.Object) + */ + public Object getParent(Object element) { + // TODO Auto-generated method stub + Assertions.UNREACHABLE(); + return null; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.viewers.ITreeContentProvider#hasChildren(java.lang.Object) + */ + public boolean hasChildren(Object element) { + return graph.getSuccNodeCount((CGNode) element) > 0; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.viewers.IStructuredContentProvider#getElements(java.lang.Object) + */ + public Object[] getElements(Object inputElement) { + Object[] firstLevelNodes = new Object[roots.size()]; + Iterator rootIt = roots.iterator(); + int i = 0; + while (rootIt.hasNext()) { + CGNode capaNode = (CGNode) rootIt.next(); + firstLevelNodes[i++] = capaNode; + } + + return firstLevelNodes; + } +} diff --git a/com.ibm.wala.eclipse/com.ibm.wala.eclipse/src/com/ibm/wala/eclipse/cg/views/CGJavaLabelProvider.java b/com.ibm.wala.eclipse/com.ibm.wala.eclipse/src/com/ibm/wala/eclipse/cg/views/CGJavaLabelProvider.java new file mode 100644 index 000000000..a218faac2 --- /dev/null +++ b/com.ibm.wala.eclipse/com.ibm.wala.eclipse/src/com/ibm/wala/eclipse/cg/views/CGJavaLabelProvider.java @@ -0,0 +1,104 @@ +package com.ibm.wala.eclipse.cg.views; + +import java.util.Map; + +import org.eclipse.jdt.core.IJavaElement; +import org.eclipse.jdt.internal.ui.JavaPlugin; +import org.eclipse.jdt.internal.ui.JavaPluginImages; +import org.eclipse.jdt.internal.ui.viewsupport.JavaElementImageProvider; +import org.eclipse.jdt.ui.JavaElementImageDescriptor; +import org.eclipse.jdt.ui.JavaElementLabelProvider; +import org.eclipse.jface.viewers.LabelProvider; +import org.eclipse.swt.graphics.Image; + +import com.ibm.wala.ipa.callgraph.CGNode; + +public class CGJavaLabelProvider extends LabelProvider { + + private Map capaNodeIdToJavaElement; + private JavaElementLabelProvider javaEltProvider; + + + public CGJavaLabelProvider(Map capaNodeIdToJavaElement) { + super(); + this.capaNodeIdToJavaElement = capaNodeIdToJavaElement; + javaEltProvider = new JavaElementLabelProvider(JavaElementLabelProvider.SHOW_PARAMETERS | + JavaElementLabelProvider.SHOW_OVERLAY_ICONS | + JavaElementLabelProvider.SHOW_POST_QUALIFIED | + JavaElementLabelProvider.SHOW_RETURN_TYPE); + } + + /* + * (non-Javadoc) + * @see org.eclipse.jface.viewers.LabelProvider#getText(java.lang.Object) + */ + @Override + public String getText(Object element) { + CGNode capaNode = (CGNode)element; + + IJavaElement jdtElt = capaNodeIdToJavaElement.get(capaNode.getGraphNodeId()); + if( jdtElt != null && jdtElt.exists() ) { + return javaEltProvider.getText(jdtElt); + } + else { + return getWalaText(capaNode); + } + } + + private String getWalaText(CGNode capaNode) { + + String className = capaNode.getMethod().getDeclaringClass().getName().toString().substring(1); + + String methodName = capaNode.getMethod().getName().toString(); + if( methodName.equals("")) { + methodName = className.substring(className.lastIndexOf('/')+1, className.length()); + } + + String params = ""; + for( int i=0; i < capaNode.getMethod().getNumberOfParameters(); i++) { + params +=capaNode.getMethod().getParameterType(i).getName() + ";"; + } + + return methodName + "(" + params + ")" + " - " + className; + } + + /* + * (non-Javadoc) + * @see org.eclipse.jface.viewers.LabelProvider#getImage(java.lang.Object) + */ + @Override + public Image getImage(Object element) { + + // get the image depending on the element + CGNode capaNode = (CGNode)element; + IJavaElement jdtElt = capaNodeIdToJavaElement.get(capaNode.getGraphNodeId()); + Image image = null; + if( jdtElt == null ) { + image = getCapaImage(); + } + else if( jdtElt.exists() ){ + image = javaEltProvider.getImage(jdtElt); + } + else { + image = getWarningImage(); + } + return image; + } + + private Image getCapaImage() { + return JavaPlugin.getImageDescriptorRegistry().get( + new JavaElementImageDescriptor( + JavaPluginImages.DESC_OBJS_CFILE, + 0, + JavaElementImageProvider.BIG_SIZE)); + } + + private Image getWarningImage() { + + return JavaPlugin.getImageDescriptorRegistry().get( + new JavaElementImageDescriptor( + JavaPluginImages.DESC_OBJS_REFACTORING_WARNING, + 0, + JavaElementImageProvider.BIG_SIZE)); + } +} diff --git a/com.ibm.wala.eclipse/com.ibm.wala.eclipse/src/com/ibm/wala/eclipse/cg/views/CGView.java b/com.ibm.wala.eclipse/com.ibm.wala.eclipse/src/com/ibm/wala/eclipse/cg/views/CGView.java new file mode 100644 index 000000000..481bdce74 --- /dev/null +++ b/com.ibm.wala.eclipse/com.ibm.wala.eclipse/src/com/ibm/wala/eclipse/cg/views/CGView.java @@ -0,0 +1,156 @@ +/******************************************************************************* + * 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.eclipse.cg.views; + +import java.util.Collection; +import java.util.Map; + +import org.eclipse.core.resources.IFile; +import org.eclipse.jdt.core.IJavaElement; +import org.eclipse.jdt.core.IJavaProject; +import org.eclipse.jdt.core.JavaModelException; +import org.eclipse.jdt.ui.JavaUI; +import org.eclipse.jface.viewers.IOpenListener; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.ITreeSelection; +import org.eclipse.jface.viewers.OpenEvent; +import org.eclipse.jface.viewers.TreeViewer; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.ui.PartInitException; +import org.eclipse.ui.part.ViewPart; + +import com.ibm.wala.eclipse.cg.model.WalaCGModel; +import com.ibm.wala.eclipse.cg.model.WalaCGModelWithMain; +import com.ibm.wala.eclipse.util.CapaToJavaEltConverter; +import com.ibm.wala.eclipse.util.JdtUtil; +import com.ibm.wala.ipa.callgraph.CGNode; +import com.ibm.wala.util.graph.Graph; +import com.ibm.wala.util.warnings.WalaException; + +/** + * This sample class demonstrates how to plug-in a new workbench view. The view + * shows data obtained from the model. The sample creates a dummy model on the + * fly, but a real implementation would connect to the model available either in + * this or another plug-in (e.g. the workspace). The view is connected to the + * model using a content provider. + *

                              + * The view uses a label provider to define how model objects should be + * presented in the view. Each view can present the same model objects using + * different labels and icons, if needed. Alternatively, a single label provider + * can be shared between views in order to ensure that objects of the same type + * are presented in the same way everywhere. + *

                              + * + * @author aying + */ + +public class CGView extends ViewPart { + + public static final String ID = "com.ibm.wala.eclipse.views.cfg.CGView"; + + private TreeViewer viewer; + + /** + * The constructor. + */ + public CGView() throws JavaModelException { + } + + /** + * This is a callback that will allow us to create the viewer and initialize + * it. + */ + public void createPartControl(Composite parent) { + IFile selectedJar = getSelectedJar(); + if( selectedJar != null ) { + createViewer(parent, selectedJar); + } + } + + private IFile getSelectedJar() { + ISelection currentSelection = getSite().getWorkbenchWindow().getSelectionService().getSelection(); + + if (currentSelection instanceof IStructuredSelection) { + Object selected = ((IStructuredSelection) currentSelection).getFirstElement(); + if (selected instanceof IFile && ((IFile) selected).getFileExtension().equals("jar")) { + return (IFile) selected; + } + } + return null; + } + + private void createViewer(Composite parent, IFile jarFile) { + try { + // get the selected jar file + String applicationJar = jarFile.getRawLocation().toString(); + IJavaProject project = JdtUtil.getJavaProject(jarFile); + + // compute the call graph + WalaCGModel model = new WalaCGModelWithMain(applicationJar); + model.buildGraph(); + Collection roots = model.getRoots(); + Graph graph = model.getGraph(); + + // convert call graph nodes to Eclipse JDT elements + final Map capaNodeIdToJavaElement = CapaToJavaEltConverter.convert( + model.getGraph(), project); + + // create the tree view + viewer = new TreeViewer(parent); + viewer.setContentProvider(new CGContentProvider(graph, roots, capaNodeIdToJavaElement)); + viewer.setLabelProvider(new CGJavaLabelProvider(capaNodeIdToJavaElement)); + viewer.setInput(getViewSite()); + viewer.addOpenListener(new IOpenListener() { + // open the file when element in the tree is clicked + public void open(OpenEvent e) { + ISelection sel = e.getSelection(); + if (sel instanceof ITreeSelection) { + ITreeSelection treeSel = (ITreeSelection) sel; + Object selectedElt = treeSel.getFirstElement(); + if (selectedElt instanceof CGNode) { + try { + CGNode capaNode = (CGNode) selectedElt; + IJavaElement jdtElt = capaNodeIdToJavaElement.get(capaNode.getGraphNodeId()); + if (jdtElt != null) { + JavaUI.revealInEditor(JavaUI.openInEditor(jdtElt), jdtElt); + } + } catch (PartInitException e1) { + // TODO Auto-generated catch block + e1.printStackTrace(); + } catch (JavaModelException e1) { + // TODO Auto-generated catch block + e1.printStackTrace(); + } + } + } + } + }); + } catch (JavaModelException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (WalaException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + + /** + * Passing the focus request to the viewer's control. + */ + public void setFocus() { + if( viewer != null && viewer.getControl() != null ) { + viewer.getControl().setFocus(); + } + } + +} \ No newline at end of file diff --git a/com.ibm.wala.eclipse/com.ibm.wala.eclipse/src/com/ibm/wala/eclipse/cg/views/SelectCapaCGAction.java b/com.ibm.wala.eclipse/com.ibm.wala.eclipse/src/com/ibm/wala/eclipse/cg/views/SelectCapaCGAction.java new file mode 100644 index 000000000..7ac61acd5 --- /dev/null +++ b/com.ibm.wala.eclipse/com.ibm.wala.eclipse/src/com/ibm/wala/eclipse/cg/views/SelectCapaCGAction.java @@ -0,0 +1,70 @@ +/******************************************************************************* + * 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.eclipse.cg.views; + +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.ui.IActionDelegate; +import org.eclipse.ui.IObjectActionDelegate; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.IWorkbenchPart; +import org.eclipse.ui.PartInitException; +import org.eclipse.ui.PlatformUI; + +public class SelectCapaCGAction implements IObjectActionDelegate { + + private ISelection currentSelection; + + /** + * Constructor for SelectionAction + */ + public SelectCapaCGAction() { + super(); + } + + /** + * @see IObjectActionDelegate#setActivePart(IAction, IWorkbenchPart) + */ + public void setActivePart(IAction action, IWorkbenchPart targetPart) { + } + + /** + * @see IActionDelegate#run(IAction) + */ + public void run(IAction action) { + if( currentSelection instanceof IStructuredSelection ) { + + IWorkbenchPage page = PlatformUI.getWorkbench().getWorkbenchWindows()[0].getPages()[0]; + CGView view = (CGView)page.findView(CGView.ID); + + if(view==null) { + try { +// IFile jarFile = (IFile)((IStructuredSelection)currentSelection).getFirstElement(); +// String applicationJar = jarFile.getRawLocation().toString(); +// String applicationJar2 = jarFile.getFullPath().toString(); + view = (CGView)page.showView(CGView.ID); + } catch (PartInitException e) { + e.printStackTrace(); + } + } + + } + } + + /** + * @see IActionDelegate#selectionChanged(IAction, ISelection) + */ + public void selectionChanged(IAction action, ISelection selection) { + currentSelection = selection; + } + +} diff --git a/com.ibm.wala.eclipse/com.ibm.wala.eclipse/src/com/ibm/wala/eclipse/util/CapaToJavaEltConverter.java b/com.ibm.wala.eclipse/com.ibm.wala.eclipse/src/com/ibm/wala/eclipse/util/CapaToJavaEltConverter.java new file mode 100644 index 000000000..239724cd2 --- /dev/null +++ b/com.ibm.wala.eclipse/com.ibm.wala.eclipse/src/com/ibm/wala/eclipse/util/CapaToJavaEltConverter.java @@ -0,0 +1,183 @@ +/******************************************************************************* + * 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.eclipse.util; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import org.eclipse.jdt.core.ICompilationUnit; +import org.eclipse.jdt.core.IJavaElement; +import org.eclipse.jdt.core.IJavaProject; +import org.eclipse.jdt.core.IMethod; +import org.eclipse.jdt.core.IType; +import org.eclipse.jdt.core.JavaModelException; +import org.eclipse.jdt.core.Signature; + +import com.ibm.wala.ipa.callgraph.CGNode; +import com.ibm.wala.types.TypeReference; +import com.ibm.wala.util.graph.Graph; + +public class CapaToJavaEltConverter { + + /** + * =Jakarta Commons CLI/test convert(Graph graph, IJavaProject javaProject) throws JavaModelException { + + Map capaNodeToJdt = new HashMap(); + Iterator capaIt = graph.iterateNodes(); + List jdtClasses = getJdtClasses(javaProject); + + while (capaIt.hasNext()) { + CGNode capaMethod = (CGNode) capaIt.next(); + String capaClassName = getLongClassName(capaMethod); + + Iterator jdtClassesIt = jdtClasses.iterator(); + while (jdtClassesIt.hasNext()) { + IType jdtClass = (IType) jdtClassesIt.next(); + + String jdtClassName = getLongClassName(jdtClass); + + if (capaClassName.equals(jdtClassName)) { + + String capaMethodName = getMethodName(capaMethod); + String[] capaParamTypes = getParamTypes(capaMethod); + IMethod method = jdtClass.getMethod(capaMethodName, capaParamTypes); + + capaNodeToJdt.put(capaMethod.getGraphNodeId(), method); + } + } + } + return capaNodeToJdt; + } + + private static List getJdtClasses(IJavaProject javaProject) { + List result = new ArrayList(); + List cus = JdtUtil.getJavaCompilationUnits(javaProject); + for (ICompilationUnit cu : cus) { + IType[] types = JdtUtil.getClasses(cu); + for (IType type : types) { + result.add(type); + } + } + return result; + } + + public static String getLongClassName(CGNode capaMethod) { + String capaTypeName = capaMethod.getMethod().getDeclaringClass().getName().toString().substring(1); + return capaTypeName; + } + + public static String getLongClassName(IType jdtClass) { + String jdtTypeName = jdtClass.getFullyQualifiedName(); + return jdtTypeName.replace('.', '/'); + } + + @SuppressWarnings("unused") + private static boolean hasSameMethodName(CGNode capaMethod, IMethod jdtMethod) { + String capaMethodName = getMethodName(capaMethod); + String jdtMethodName = getMethodName(jdtMethod); + return capaMethodName.equals(jdtMethodName); + } + + private static String getMethodName(CGNode capaMethod) { + String capaMethodName = capaMethod.getMethod().getName().toString(); + if (capaMethodName.equals("")) { + capaMethodName = capaMethod.getMethod().getDeclaringClass().getName().toString().substring( + capaMethod.getMethod().getDeclaringClass().getName().toString().lastIndexOf('/') + 1, + capaMethod.getMethod().getDeclaringClass().getName().toString().length()); + } + return capaMethodName; + } + + private static String getMethodName(IMethod jdtMethod) { + return jdtMethod.getElementName(); + } + + private static String[] getParamTypes(CGNode capaMethod) { + + List capaParams = getParams(capaMethod); + Iterator capaParamsIt = capaParams.iterator(); + String[] result = new String[capaParams.size()]; + + // check the type of each param + for (int i = 0; capaParamsIt.hasNext(); i++) { + + TypeReference capaParamType = (TypeReference) capaParamsIt.next(); + String type = ""; + String arrayType = ""; + + // TODO should handle multi-dimenional arrays + // this assumes is 1-D array + if (capaParamType.isArrayType()) { + arrayType = "[]"; + + // get the array element + capaParamType = capaParamType.getArrayElementType(); + } + + if (capaParamType.isPrimitiveType()) { + String capaType = capaParamType.getName().toString(); + if (capaType.equals("C")) + type = "char"; + else if (capaType.equals("Z")) + type = "boolean"; + else if (capaType.equals("I")) + type = "int"; + else if (capaType.equals("B")) + type = "byte"; + else if (capaType.equals("D")) + type = "double"; + else if (capaType.equals("F")) + type = "float"; + else if (capaType.equals("J")) + type = "long"; + else if (capaType.equals("S")) + type = "short"; + } else if (capaParamType.isClassType()) { + type = capaParamType.getName().toString().substring(capaParamType.getName().getPackage().length() + 2, + capaParamType.getName().toString().length()); + + } + result[i] = Signature.createTypeSignature(type + arrayType, false); + } + return result; + } + + private static List getParams(CGNode node) { + int nbrParamsIncludingThisRef = node.getMethod().getNumberOfParameters(); + List result = new ArrayList(nbrParamsIncludingThisRef); + int startParamNbr = 0; + if (node.getMethod().isStatic() || node.getMethod().isClinit()) { + startParamNbr = 0; + } else { + startParamNbr = 1; + } + + for (int i = startParamNbr; i < nbrParamsIncludingThisRef; i++) { + result.add(node.getMethod().getParameterType(i)); + } + return result; + } + + @SuppressWarnings("unused") + private static String[] getSimpleParamTypes(IMethod jdtMethod) { + String[] paramTypes = jdtMethod.getParameterTypes(); + String[] humanReadableTypes = new String[paramTypes.length]; + for (String paramType : paramTypes) { + JdtUtil.getHumanReadableType(paramType); + } + return humanReadableTypes; + } +} diff --git a/com.ibm.wala.eclipse/com.ibm.wala.eclipse/src/com/ibm/wala/eclipse/util/JdtUtil.java b/com.ibm.wala.eclipse/com.ibm.wala.eclipse/src/com/ibm/wala/eclipse/util/JdtUtil.java new file mode 100644 index 000000000..8d6bd1ef8 --- /dev/null +++ b/com.ibm.wala.eclipse/com.ibm.wala.eclipse/src/com/ibm/wala/eclipse/util/JdtUtil.java @@ -0,0 +1,188 @@ +/******************************************************************************* + * 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.eclipse.util; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IWorkspaceRoot; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.jdt.core.ICompilationUnit; +import org.eclipse.jdt.core.IJavaElement; +import org.eclipse.jdt.core.IJavaModel; +import org.eclipse.jdt.core.IJavaProject; +import org.eclipse.jdt.core.IMethod; +import org.eclipse.jdt.core.IPackageDeclaration; +import org.eclipse.jdt.core.IPackageFragment; +import org.eclipse.jdt.core.IPackageFragmentRoot; +import org.eclipse.jdt.core.IType; +import org.eclipse.jdt.core.JavaCore; +import org.eclipse.jdt.core.JavaModelException; +import org.eclipse.jdt.core.Signature; +import org.eclipse.jdt.internal.core.JarPackageFragmentRoot; + +/** + * Convenience methods to get information from JDT IJavaElement model. + * + * @author aying + */ +public class JdtUtil { + + public static String getFilePath(IJavaElement javaElt) { + String filePath = javaElt.getPath().toString(); + return filePath; + } + + public static String getPackageName(ICompilationUnit cu) { + try { + IPackageDeclaration[] pkgDecl = cu.getPackageDeclarations(); + + // TODO: handle default package? + if( pkgDecl != null && pkgDecl.length > 0 ) { + String packageName = pkgDecl[0].getElementName(); + return packageName; + } + } catch (JavaModelException e) { + + } + return ""; + + } + + public static String getFullyQualifiedClassName(IType type) { + ICompilationUnit cu = (ICompilationUnit)type.getParent(); + String packageName = getPackageName(cu); + String className = type.getElementName(); + String fullyQName = packageName + "." + className; + return fullyQName; + } + + public static String getClassName(IType type) { + String className = type.getElementName(); + return className; + } + + public static String getMethodSignature(IMethod method) { + try { + String methodParamReturnInfo = method.getSignature(); + String methodName = method.getElementName(); + String methodSignature = methodName + " " + methodParamReturnInfo; + return methodSignature; + } catch (JavaModelException e) { + } + return ""; + } + + /** + * Return a unique string representing the specified + * Java element across projects in the workspace. + * The returned string can be used as a handle to create + * JavaElement by 'JavaCore.create(String)' + * + * For example, suppose we have the method + * 'fooPackage.barPackage.FooClass.fooMethod(int)' + * which is in the 'FooProject' and source folder 'src' + * the handle would be + * '=FooProject/src getJavaCompilationUnits(IJavaProject javaProject) { + List cuResult = new ArrayList(); + try { + if( javaProject.hasChildren() ) { + IPackageFragmentRoot[] packFragRoots = javaProject.getPackageFragmentRoots(); + for (int i = 0; i < packFragRoots.length; i++) { + IPackageFragmentRoot packFragRoot = packFragRoots[i]; + if ( packFragRoot instanceof JarPackageFragmentRoot == false + && packFragRoot.hasChildren()) { + IJavaElement[] packFrags = packFragRoot.getChildren(); + for (int j = 0; j < packFrags.length; j++) { + ICompilationUnit[] cus = ((IPackageFragment) packFrags[j]).getCompilationUnits(); + if (cus != null) { + Collections.addAll(cuResult, cus); + } + } + } + } + } + } catch (JavaModelException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + return cuResult; + } + + public static IType[] getClasses(ICompilationUnit cu) { + try { + return cu.getAllTypes(); + } + catch(JavaModelException e) { + + } + return null; + } + + public static IJavaProject getProject(IJavaElement javaElt) { + IJavaProject javaProject = javaElt.getJavaProject(); + return javaProject; + } + + public static String getProjectName(IJavaProject javaProject) { + return javaProject.getElementName(); + } + + + /** + * @param typeSignature Some of the type signatures examples are "QString;" (String) + * and "I" (int) + * The type signatures may be either unresolved (for source types) + * or resolved (for binary types), and either basic (for basic types) + * or rich (for parameterized types). See {@link Signature} for details. + */ + public static String getHumanReadableType(String typeSignature) { + String simpleName = Signature.getSignatureSimpleName(typeSignature); + return simpleName; + } + + + public static IJavaProject getJavaProject(IFile appJar) { + String projectName = appJar.getProject().getName(); + IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot(); + IJavaModel javaModel = JavaCore.create(workspaceRoot); + IJavaProject javaProject = javaModel.getJavaProject(projectName); + return javaProject; + } + + public static IJavaProject getHelloWorldProject() { + IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot(); + IJavaModel javaModel = JavaCore.create(workspaceRoot); + IJavaProject helloWorldProject = javaModel.getJavaProject("HelloWorld"); + return helloWorldProject; + } + + public static IFile getHelloWorldJar() { + IJavaProject project = getHelloWorldProject(); + IFile helloWorldJar = project.getProject().getFile("helloWorld.jar"); + return helloWorldJar; + } +} diff --git a/com.ibm.wala.eclipse/icons/Wala-icon.jpg b/com.ibm.wala.eclipse/icons/Wala-icon.jpg new file mode 100644 index 000000000..9dfddbbf3 Binary files /dev/null and b/com.ibm.wala.eclipse/icons/Wala-icon.jpg differ diff --git a/com.ibm.wala.eclipse/javaCompiler...args b/com.ibm.wala.eclipse/javaCompiler...args new file mode 100644 index 000000000..783f6aaf9 --- /dev/null +++ b/com.ibm.wala.eclipse/javaCompiler...args @@ -0,0 +1,74 @@ +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.ui_3.2.0.I20060605-1400.jar[~org/eclipse/ui/internal/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.core.runtime_3.2.0.v20060603.jar[~org/eclipse/core/internal/preferences/legacy/*;~org/eclipse/core/internal/runtime/*;+org/eclipse/core/runtime/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.osgi_3.2.0.v20060601.jar[+org/eclipse/osgi/event/*;+org/eclipse/osgi/framework/console/*;+org/eclipse/osgi/framework/eventmgr/*;+org/eclipse/osgi/framework/log/*;+org/eclipse/osgi/service/datalocation/*;+org/eclipse/osgi/service/debug/*;+org/eclipse/osgi/service/environment/*;+org/eclipse/osgi/service/localization/*;+org/eclipse/osgi/service/pluginconversion/*;+org/eclipse/osgi/service/resolver/*;+org/eclipse/osgi/service/runnable/*;+org/eclipse/osgi/service/urlconversion/*;+org/eclipse/osgi/storagemanager/*;+org/eclipse/osgi/util/*;+org/osgi/framework/*;+org/osgi/service/condpermadmin/*;+org/osgi/service/packageadmin/*;+org/osgi/service/permissionadmin/*;+org/osgi/service/startlevel/*;+org/osgi/service/url/*;+org/osgi/util/tracker/*;~org/eclipse/core/runtime/adaptor/*;~org/eclipse/core/runtime/internal/adaptor/*;~org/eclipse/core/runtime/internal/stats/*;~org/eclipse/osgi/baseadaptor/*;~org/eclipse/osgi/baseadaptor/bundlefile/*;~org/eclipse/osgi/baseadaptor/hooks/*;~org/eclipse/osgi/baseadaptor/loader/*;~org/eclipse/osgi/framework/adaptor/*;~org/eclipse/osgi/framework/debug/*;~org/eclipse/osgi/framework/internal/core/*;~org/eclipse/osgi/framework/internal/protocol/*;~org/eclipse/osgi/framework/internal/protocol/bundleentry/*;~org/eclipse/osgi/framework/internal/protocol/bundleresource/*;~org/eclipse/osgi/framework/internal/protocol/reference/*;~org/eclipse/osgi/framework/internal/reliablefile/*;~org/eclipse/osgi/framework/launcher/*;~org/eclipse/osgi/framework/util/*;~org/eclipse/osgi/internal/baseadaptor/*;~org/eclipse/osgi/internal/module/*;~org/eclipse/osgi/internal/profile/*;~org/eclipse/osgi/internal/resolver/*;~org/eclipse/osgi/internal/verifier/*;~org/eclipse/osgi/internal/provisional/verifier/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.equinox.common_3.2.0.v20060603.jar[~org/eclipse/core/internal/runtime/*;~org/eclipse/core/internal/boot/*;+org/eclipse/core/runtime/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.core.jobs_3.2.0.v20060603.jar[~org/eclipse/core/internal/jobs/*;+org/eclipse/core/runtime/jobs/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.core.runtime.compatibility.registry_3.2.0.v20060603/runtime_registry_compatibility.jar[~org/eclipse/core/internal/registry/*;~org/eclipse/core/internal/registry/osgi/*;~org/eclipse/core/internal/registry/spi/*;+org/eclipse/core/runtime/*;+org/eclipse/core/runtime/dynamichelpers/*;+org/eclipse/core/runtime/spi/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.core.runtime.compatibility.registry_3.2.0.v20060603[~org/eclipse/core/internal/registry/*;~org/eclipse/core/internal/registry/osgi/*;~org/eclipse/core/internal/registry/spi/*;+org/eclipse/core/runtime/*;+org/eclipse/core/runtime/dynamichelpers/*;+org/eclipse/core/runtime/spi/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.equinox.registry_3.2.0.v20060601.jar[~org/eclipse/core/internal/registry/*;~org/eclipse/core/internal/registry/osgi/*;~org/eclipse/core/internal/registry/spi/*;+org/eclipse/core/runtime/*;+org/eclipse/core/runtime/dynamichelpers/*;+org/eclipse/core/runtime/spi/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.apache.xerces_2.8.0.v200606131651/resolver.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.apache.xerces_2.8.0.v200606131651/xercesImpl.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.apache.xerces_2.8.0.v200606131651/xml-apis.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.equinox.preferences_3.2.0.v20060601.jar[~org/eclipse/core/internal/preferences/*;~org/eclipse/core/internal/preferences/exchange/*;+org/eclipse/core/runtime/preferences/*;+org/osgi/service/prefs/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.core.runtime.compatibility.registry_3.2.0.v20060603/@dot[~org/eclipse/core/internal/registry/*;~org/eclipse/core/internal/registry/osgi/*;~org/eclipse/core/internal/registry/spi/*;+org/eclipse/core/runtime/*;+org/eclipse/core/runtime/dynamichelpers/*;+org/eclipse/core/runtime/spi/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.core.contenttype_3.2.0.v20060603.jar[~org/eclipse/core/internal/content/*;+org/eclipse/core/runtime/content/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.core.runtime.compatibility.auth_3.2.0.v20060601.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.swt_3.2.0.v3232o.jar[+org/eclipse/swt/*;+org/eclipse/swt/accessibility/*;+org/eclipse/swt/awt/*;+org/eclipse/swt/browser/*;+org/eclipse/swt/custom/*;+org/eclipse/swt/dnd/*;+org/eclipse/swt/events/*;+org/eclipse/swt/graphics/*;+org/eclipse/swt/layout/*;+org/eclipse/swt/opengl/*;+org/eclipse/swt/printing/*;+org/eclipse/swt/program/*;+org/eclipse/swt/widgets/*;~org/eclipse/swt/internal/*;~org/eclipse/swt/internal/image/*;~org/eclipse/swt/internal/theme/*;+org/eclipse/swt/ole/win32/*;~org/eclipse/swt/internal/gdip/*;~org/eclipse/swt/internal/ole/win32/*;~org/eclipse/swt/internal/win32/*;~org/eclipse/swt/internal/opengl/win32/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.swt.win32.win32.x86_3.2.0.v3232m.jar[+org/eclipse/swt/*;+org/eclipse/swt/accessibility/*;+org/eclipse/swt/awt/*;+org/eclipse/swt/browser/*;+org/eclipse/swt/custom/*;+org/eclipse/swt/dnd/*;+org/eclipse/swt/events/*;+org/eclipse/swt/graphics/*;+org/eclipse/swt/layout/*;+org/eclipse/swt/opengl/*;+org/eclipse/swt/printing/*;+org/eclipse/swt/program/*;+org/eclipse/swt/widgets/*;~org/eclipse/swt/internal/*;~org/eclipse/swt/internal/image/*;~org/eclipse/swt/internal/theme/*;+org/eclipse/swt/ole/win32/*;~org/eclipse/swt/internal/gdip/*;~org/eclipse/swt/internal/ole/win32/*;~org/eclipse/swt/internal/win32/*;~org/eclipse/swt/internal/opengl/win32/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.jface_3.2.0.I20060605-1400.jar[+org/eclipse/jface/*;+org/eclipse/jface/action/*;+org/eclipse/jface/action/images/*;+org/eclipse/jface/bindings/*;+org/eclipse/jface/bindings/keys/*;+org/eclipse/jface/bindings/keys/formatting/*;+org/eclipse/jface/commands/*;+org/eclipse/jface/contexts/*;+org/eclipse/jface/dialogs/*;+org/eclipse/jface/dialogs/images/*;+org/eclipse/jface/fieldassist/*;+org/eclipse/jface/fieldassist/images/*;+org/eclipse/jface/images/*;~org/eclipse/jface/internal/provisional/action/*;+org/eclipse/jface/layout/*;+org/eclipse/jface/menus/*;+org/eclipse/jface/operation/*;+org/eclipse/jface/preference/*;+org/eclipse/jface/preference/images/*;+org/eclipse/jface/resource/*;+org/eclipse/jface/util/*;+org/eclipse/jface/viewers/*;+org/eclipse/jface/viewers/deferred/*;+org/eclipse/jface/window/*;+org/eclipse/jface/wizard/*;+org/eclipse/jface/wizard/images/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.core.commands_3.2.0.I20060605-1400.jar[+org/eclipse/core/commands/*;+org/eclipse/core/commands/common/*;+org/eclipse/core/commands/contexts/*;+org/eclipse/core/commands/operations/*;+org/eclipse/core/commands/util/*;~org/eclipse/core/internal/commands/operations/*;~org/eclipse/core/internal/commands/util/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.ui.workbench_3.2.0.I20060605-1400.jar[+org/eclipse/ui/*;+org/eclipse/ui/about/*;+org/eclipse/ui/actions/*;+org/eclipse/ui/activities/*;+org/eclipse/ui/application/*;+org/eclipse/ui/branding/*;+org/eclipse/ui/browser/*;+org/eclipse/ui/commands/*;+org/eclipse/ui/contexts/*;+org/eclipse/ui/dialogs/*;+org/eclipse/ui/fieldassist/*;+org/eclipse/ui/handlers/*;+org/eclipse/ui/help/*;~org/eclipse/ui/internal/*;~org/eclipse/ui/internal/about/*;~org/eclipse/ui/internal/actions/*;~org/eclipse/ui/internal/activities/*;~org/eclipse/ui/internal/activities/ws/*;~org/eclipse/ui/internal/application/*;~org/eclipse/ui/internal/browser/*;~org/eclipse/ui/internal/commands/*;~org/eclipse/ui/internal/contexts/*;~org/eclipse/ui/internal/decorators/*;~org/eclipse/ui/internal/dialogs/*;~org/eclipse/ui/internal/dnd/*;~org/eclipse/ui/internal/editorsupport/*;~org/eclipse/ui/internal/expressions/*;~org/eclipse/ui/internal/handlers/*;~org/eclipse/ui/internal/help/*;~org/eclipse/ui/internal/intro/*;~org/eclipse/ui/internal/keys/*;~org/eclipse/ui/internal/layout/*;~org/eclipse/ui/internal/menus/*;~org/eclipse/ui/internal/misc/*;~org/eclipse/ui/internal/operations/*;~org/eclipse/ui/internal/part/*;~org/eclipse/ui/internal/preferences/*;~org/eclipse/ui/internal/presentations/*;~org/eclipse/ui/internal/presentations/defaultpresentation/*;~org/eclipse/ui/internal/presentations/util/*;~org/eclipse/ui/internal/progress/*;~org/eclipse/ui/internal/provisional/application/*;~org/eclipse/ui/internal/provisional/presentations/*;~org/eclipse/ui/internal/registry/*;~org/eclipse/ui/internal/services/*;~org/eclipse/ui/internal/testing/*;~org/eclipse/ui/internal/themes/*;~org/eclipse/ui/internal/util/*;~org/eclipse/ui/internal/wizards/*;~org/eclipse/ui/internal/wizards/preferences/*;+org/eclipse/ui/intro/*;+org/eclipse/ui/keys/*;+org/eclipse/ui/menus/*;+org/eclipse/ui/model/*;+org/eclipse/ui/operations/*;+org/eclipse/ui/part/*;+org/eclipse/ui/plugin/*;+org/eclipse/ui/preferences/*;+org/eclipse/ui/presentations/*;+org/eclipse/ui/progress/*;+org/eclipse/ui/services/*;+org/eclipse/ui/testing/*;+org/eclipse/ui/themes/*;+org/eclipse/ui/views/*;+org/eclipse/ui/wizards/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.ui.workbench.compatibility_3.2.0.I20060605-1400/@dot[+org/eclipse/ui/*;+org/eclipse/ui/about/*;+org/eclipse/ui/actions/*;+org/eclipse/ui/activities/*;+org/eclipse/ui/application/*;+org/eclipse/ui/branding/*;+org/eclipse/ui/browser/*;+org/eclipse/ui/commands/*;+org/eclipse/ui/contexts/*;+org/eclipse/ui/dialogs/*;+org/eclipse/ui/fieldassist/*;+org/eclipse/ui/handlers/*;+org/eclipse/ui/help/*;~org/eclipse/ui/internal/*;~org/eclipse/ui/internal/about/*;~org/eclipse/ui/internal/actions/*;~org/eclipse/ui/internal/activities/*;~org/eclipse/ui/internal/activities/ws/*;~org/eclipse/ui/internal/application/*;~org/eclipse/ui/internal/browser/*;~org/eclipse/ui/internal/commands/*;~org/eclipse/ui/internal/contexts/*;~org/eclipse/ui/internal/decorators/*;~org/eclipse/ui/internal/dialogs/*;~org/eclipse/ui/internal/dnd/*;~org/eclipse/ui/internal/editorsupport/*;~org/eclipse/ui/internal/expressions/*;~org/eclipse/ui/internal/handlers/*;~org/eclipse/ui/internal/help/*;~org/eclipse/ui/internal/intro/*;~org/eclipse/ui/internal/keys/*;~org/eclipse/ui/internal/layout/*;~org/eclipse/ui/internal/menus/*;~org/eclipse/ui/internal/misc/*;~org/eclipse/ui/internal/operations/*;~org/eclipse/ui/internal/part/*;~org/eclipse/ui/internal/preferences/*;~org/eclipse/ui/internal/presentations/*;~org/eclipse/ui/internal/presentations/defaultpresentation/*;~org/eclipse/ui/internal/presentations/util/*;~org/eclipse/ui/internal/progress/*;~org/eclipse/ui/internal/provisional/application/*;~org/eclipse/ui/internal/provisional/presentations/*;~org/eclipse/ui/internal/registry/*;~org/eclipse/ui/internal/services/*;~org/eclipse/ui/internal/testing/*;~org/eclipse/ui/internal/themes/*;~org/eclipse/ui/internal/util/*;~org/eclipse/ui/internal/wizards/*;~org/eclipse/ui/internal/wizards/preferences/*;+org/eclipse/ui/intro/*;+org/eclipse/ui/keys/*;+org/eclipse/ui/menus/*;+org/eclipse/ui/model/*;+org/eclipse/ui/operations/*;+org/eclipse/ui/part/*;+org/eclipse/ui/plugin/*;+org/eclipse/ui/preferences/*;+org/eclipse/ui/presentations/*;+org/eclipse/ui/progress/*;+org/eclipse/ui/services/*;+org/eclipse/ui/testing/*;+org/eclipse/ui/themes/*;+org/eclipse/ui/views/*;+org/eclipse/ui/wizards/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.ui.workbench.compatibility_3.2.0.I20060605-1400/compatibility.jar[+org/eclipse/ui/*;+org/eclipse/ui/about/*;+org/eclipse/ui/actions/*;+org/eclipse/ui/activities/*;+org/eclipse/ui/application/*;+org/eclipse/ui/branding/*;+org/eclipse/ui/browser/*;+org/eclipse/ui/commands/*;+org/eclipse/ui/contexts/*;+org/eclipse/ui/dialogs/*;+org/eclipse/ui/fieldassist/*;+org/eclipse/ui/handlers/*;+org/eclipse/ui/help/*;~org/eclipse/ui/internal/*;~org/eclipse/ui/internal/about/*;~org/eclipse/ui/internal/actions/*;~org/eclipse/ui/internal/activities/*;~org/eclipse/ui/internal/activities/ws/*;~org/eclipse/ui/internal/application/*;~org/eclipse/ui/internal/browser/*;~org/eclipse/ui/internal/commands/*;~org/eclipse/ui/internal/contexts/*;~org/eclipse/ui/internal/decorators/*;~org/eclipse/ui/internal/dialogs/*;~org/eclipse/ui/internal/dnd/*;~org/eclipse/ui/internal/editorsupport/*;~org/eclipse/ui/internal/expressions/*;~org/eclipse/ui/internal/handlers/*;~org/eclipse/ui/internal/help/*;~org/eclipse/ui/internal/intro/*;~org/eclipse/ui/internal/keys/*;~org/eclipse/ui/internal/layout/*;~org/eclipse/ui/internal/menus/*;~org/eclipse/ui/internal/misc/*;~org/eclipse/ui/internal/operations/*;~org/eclipse/ui/internal/part/*;~org/eclipse/ui/internal/preferences/*;~org/eclipse/ui/internal/presentations/*;~org/eclipse/ui/internal/presentations/defaultpresentation/*;~org/eclipse/ui/internal/presentations/util/*;~org/eclipse/ui/internal/progress/*;~org/eclipse/ui/internal/provisional/application/*;~org/eclipse/ui/internal/provisional/presentations/*;~org/eclipse/ui/internal/registry/*;~org/eclipse/ui/internal/services/*;~org/eclipse/ui/internal/testing/*;~org/eclipse/ui/internal/themes/*;~org/eclipse/ui/internal/util/*;~org/eclipse/ui/internal/wizards/*;~org/eclipse/ui/internal/wizards/preferences/*;+org/eclipse/ui/intro/*;+org/eclipse/ui/keys/*;+org/eclipse/ui/menus/*;+org/eclipse/ui/model/*;+org/eclipse/ui/operations/*;+org/eclipse/ui/part/*;+org/eclipse/ui/plugin/*;+org/eclipse/ui/preferences/*;+org/eclipse/ui/presentations/*;+org/eclipse/ui/progress/*;+org/eclipse/ui/services/*;+org/eclipse/ui/testing/*;+org/eclipse/ui/themes/*;+org/eclipse/ui/views/*;+org/eclipse/ui/wizards/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/com.ibm.icu_3.4.4.1.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.help_3.2.0.v20060602.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.core.expressions_3.2.0.v20060605-1400.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.core.resources_3.2.0.v20060603.jar[~org/eclipse/core/internal/dtree/*;~org/eclipse/core/internal/events/*;~org/eclipse/core/internal/localstore/*;~org/eclipse/core/internal/properties/*;~org/eclipse/core/internal/propertytester/*;~org/eclipse/core/internal/refresh/*;~org/eclipse/core/internal/resources/*;~org/eclipse/core/internal/resources/mapping/*;~org/eclipse/core/internal/utils/*;~org/eclipse/core/internal/watson/*;+org/eclipse/core/resources/*;+org/eclipse/core/resources/mapping/*;+org/eclipse/core/resources/refresh/*;+org/eclipse/core/resources/team/*;~org/eclipse/core/internal/indexing/*;~org/eclipse/core/internal/resources/refresh/win32/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.core.resources.compatibility_3.2.0.v20060603.jar[~org/eclipse/core/internal/dtree/*;~org/eclipse/core/internal/events/*;~org/eclipse/core/internal/localstore/*;~org/eclipse/core/internal/properties/*;~org/eclipse/core/internal/propertytester/*;~org/eclipse/core/internal/refresh/*;~org/eclipse/core/internal/resources/*;~org/eclipse/core/internal/resources/mapping/*;~org/eclipse/core/internal/utils/*;~org/eclipse/core/internal/watson/*;+org/eclipse/core/resources/*;+org/eclipse/core/resources/mapping/*;+org/eclipse/core/resources/refresh/*;+org/eclipse/core/resources/team/*;~org/eclipse/core/internal/indexing/*;~org/eclipse/core/internal/resources/refresh/win32/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.core.resources.win32_3.2.0.v20060603.jar[~org/eclipse/core/internal/dtree/*;~org/eclipse/core/internal/events/*;~org/eclipse/core/internal/localstore/*;~org/eclipse/core/internal/properties/*;~org/eclipse/core/internal/propertytester/*;~org/eclipse/core/internal/refresh/*;~org/eclipse/core/internal/resources/*;~org/eclipse/core/internal/resources/mapping/*;~org/eclipse/core/internal/utils/*;~org/eclipse/core/internal/watson/*;+org/eclipse/core/resources/*;+org/eclipse/core/resources/mapping/*;+org/eclipse/core/resources/refresh/*;+org/eclipse/core/resources/team/*;~org/eclipse/core/internal/indexing/*;~org/eclipse/core/internal/resources/refresh/win32/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.core.runtime.compatibility_3.1.100.v20060603.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.update.configurator_3.2.0.v20060605.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.ant.core_3.1.100.v20060531.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.core.variables_3.1.100.v20060605.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.core.filesystem_1.0.0.v20060603.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.core.filesystem.win32.x86_1.0.0.v20060603.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.jdt.core_3.2.0.v_671.jar[+org/eclipse/jdt/core/*;+org/eclipse/jdt/core/compiler/*;+org/eclipse/jdt/core/dom/*;+org/eclipse/jdt/core/dom/rewrite/*;+org/eclipse/jdt/core/eval/*;+org/eclipse/jdt/core/formatter/*;+org/eclipse/jdt/core/jdom/*;+org/eclipse/jdt/core/search/*;+org/eclipse/jdt/core/util/*;~org/eclipse/jdt/internal/codeassist/*;~org/eclipse/jdt/internal/codeassist/complete/*;~org/eclipse/jdt/internal/codeassist/impl/*;~org/eclipse/jdt/internal/codeassist/select/*;~org/eclipse/jdt/internal/compiler/*;~org/eclipse/jdt/internal/compiler/ast/*;~org/eclipse/jdt/internal/compiler/batch/*;~org/eclipse/jdt/internal/compiler/classfmt/*;~org/eclipse/jdt/internal/compiler/codegen/*;~org/eclipse/jdt/internal/compiler/env/*;~org/eclipse/jdt/internal/compiler/flow/*;~org/eclipse/jdt/internal/compiler/impl/*;~org/eclipse/jdt/internal/compiler/lookup/*;~org/eclipse/jdt/internal/compiler/parser/*;~org/eclipse/jdt/internal/compiler/parser/diagnose/*;~org/eclipse/jdt/internal/compiler/problem/*;~org/eclipse/jdt/internal/compiler/util/*;~org/eclipse/jdt/internal/core/*;~org/eclipse/jdt/internal/core/builder/*;~org/eclipse/jdt/internal/core/dom/rewrite/*;~org/eclipse/jdt/internal/core/eval/*;~org/eclipse/jdt/internal/core/hierarchy/*;~org/eclipse/jdt/internal/core/index/*;~org/eclipse/jdt/internal/core/jdom/*;~org/eclipse/jdt/internal/core/search/*;~org/eclipse/jdt/internal/core/search/indexing/*;~org/eclipse/jdt/internal/core/search/matching/*;~org/eclipse/jdt/internal/core/search/processing/*;~org/eclipse/jdt/internal/core/util/*;~org/eclipse/jdt/internal/eval/*;~org/eclipse/jdt/internal/formatter/*;~org/eclipse/jdt/internal/formatter/align/*;~org/eclipse/jdt/internal/formatter/comment/*;~org/eclipse/jdt/internal/formatter/old/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.text_3.2.0.v20060605-1400.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.team.core_3.2.0.I200606051140.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.jdt.ui_3.2.0.v20060605-1400.jar[~org/eclipse/jdt/internal/corext/*;~org/eclipse/jdt/internal/corext/buildpath/*;~org/eclipse/jdt/internal/corext/callhierarchy/*;~org/eclipse/jdt/internal/corext/codemanipulation/*;~org/eclipse/jdt/internal/corext/dom/*;~org/eclipse/jdt/internal/corext/dom/fragments/*;~org/eclipse/jdt/internal/corext/fix/*;~org/eclipse/jdt/internal/corext/javadoc/*;~org/eclipse/jdt/internal/corext/refactoring/*;~org/eclipse/jdt/internal/corext/refactoring/base/*;~org/eclipse/jdt/internal/corext/refactoring/binary/*;~org/eclipse/jdt/internal/corext/refactoring/changes/*;~org/eclipse/jdt/internal/corext/refactoring/code/*;~org/eclipse/jdt/internal/corext/refactoring/code/flow/*;~org/eclipse/jdt/internal/corext/refactoring/delegates/*;~org/eclipse/jdt/internal/corext/refactoring/generics/*;~org/eclipse/jdt/internal/corext/refactoring/nls/*;~org/eclipse/jdt/internal/corext/refactoring/nls/changes/*;~org/eclipse/jdt/internal/corext/refactoring/participants/*;~org/eclipse/jdt/internal/corext/refactoring/rename/*;~org/eclipse/jdt/internal/corext/refactoring/reorg/*;~org/eclipse/jdt/internal/corext/refactoring/scripting/*;~org/eclipse/jdt/internal/corext/refactoring/sef/*;~org/eclipse/jdt/internal/corext/refactoring/structure/*;~org/eclipse/jdt/internal/corext/refactoring/structure/constraints/*;~org/eclipse/jdt/internal/corext/refactoring/surround/*;~org/eclipse/jdt/internal/corext/refactoring/tagging/*;~org/eclipse/jdt/internal/corext/refactoring/typeconstraints/*;~org/eclipse/jdt/internal/corext/refactoring/typeconstraints/types/*;~org/eclipse/jdt/internal/corext/refactoring/typeconstraints/typesets/*;~org/eclipse/jdt/internal/corext/refactoring/typeconstraints2/*;~org/eclipse/jdt/internal/corext/refactoring/util/*;~org/eclipse/jdt/internal/corext/template/java/*;~org/eclipse/jdt/internal/corext/util/*;~org/eclipse/jdt/internal/ui/*;~org/eclipse/jdt/internal/ui/actions/*;~org/eclipse/jdt/internal/ui/browsing/*;~org/eclipse/jdt/internal/ui/callhierarchy/*;~org/eclipse/jdt/internal/ui/commands/*;~org/eclipse/jdt/internal/ui/compare/*;~org/eclipse/jdt/internal/ui/dialogs/*;~org/eclipse/jdt/internal/ui/dnd/*;~org/eclipse/jdt/internal/ui/filters/*;~org/eclipse/jdt/internal/ui/fix/*;~org/eclipse/jdt/internal/ui/infoviews/*;~org/eclipse/jdt/internal/ui/jarimport/*;~org/eclipse/jdt/internal/ui/jarpackager/*;~org/eclipse/jdt/internal/ui/javadocexport/*;~org/eclipse/jdt/internal/ui/javaeditor/*;~org/eclipse/jdt/internal/ui/javaeditor/selectionactions/*;~org/eclipse/jdt/internal/ui/model/*;~org/eclipse/jdt/internal/ui/navigator/*;~org/eclipse/jdt/internal/ui/packageview/*;~org/eclipse/jdt/internal/ui/preferences/*;~org/eclipse/jdt/internal/ui/preferences/formatter/*;~org/eclipse/jdt/internal/ui/propertiesfileeditor/*;~org/eclipse/jdt/internal/ui/refactoring/*;~org/eclipse/jdt/internal/ui/refactoring/actions/*;~org/eclipse/jdt/internal/ui/refactoring/binary/*;~org/eclipse/jdt/internal/ui/refactoring/code/*;~org/eclipse/jdt/internal/ui/refactoring/contentassist/*;~org/eclipse/jdt/internal/ui/refactoring/nls/*;~org/eclipse/jdt/internal/ui/refactoring/nls/search/*;~org/eclipse/jdt/internal/ui/refactoring/reorg/*;~org/eclipse/jdt/internal/ui/refactoring/sef/*;~org/eclipse/jdt/internal/ui/search/*;~org/eclipse/jdt/internal/ui/text/*;~org/eclipse/jdt/internal/ui/text/comment/*;~org/eclipse/jdt/internal/ui/text/correction/*;~org/eclipse/jdt/internal/ui/text/folding/*;~org/eclipse/jdt/internal/ui/text/java/*;~org/eclipse/jdt/internal/ui/text/java/hover/*;~org/eclipse/jdt/internal/ui/text/javadoc/*;~org/eclipse/jdt/internal/ui/text/spelling/*;~org/eclipse/jdt/internal/ui/text/spelling/engine/*;~org/eclipse/jdt/internal/ui/text/template/contentassist/*;~org/eclipse/jdt/internal/ui/text/template/preferences/*;~org/eclipse/jdt/internal/ui/typehierarchy/*;~org/eclipse/jdt/internal/ui/util/*;~org/eclipse/jdt/internal/ui/viewsupport/*;~org/eclipse/jdt/internal/ui/wizards/*;~org/eclipse/jdt/internal/ui/wizards/buildpaths/*;~org/eclipse/jdt/internal/ui/wizards/buildpaths/newsourcepage/*;~org/eclipse/jdt/internal/ui/wizards/dialogfields/*;~org/eclipse/jdt/internal/ui/workingsets/*;+org/eclipse/jdt/ui/*;+org/eclipse/jdt/ui/actions/*;+org/eclipse/jdt/ui/dialogs/*;+org/eclipse/jdt/ui/jarpackager/*;+org/eclipse/jdt/ui/refactoring/*;+org/eclipse/jdt/ui/search/*;+org/eclipse/jdt/ui/text/*;+org/eclipse/jdt/ui/text/folding/*;+org/eclipse/jdt/ui/text/java/*;+org/eclipse/jdt/ui/text/java/hover/*;+org/eclipse/jdt/ui/wizards/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.ui.console_3.1.100.v20060605.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.jface.text_3.2.0.v20060605-1400.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.ui.workbench.texteditor_3.2.0.v20060605-1400.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.search_3.2.0.v20060605-1400.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.core.filebuffers_3.2.0.v20060605-1400.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.ui.ide_3.2.0.I20060605-1400.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.ui.win32_3.2.0.I20060605-1400.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.ui.views_3.2.0.I20060605-1400.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.update.core_3.2.0.v20060605.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.update.core.win32_3.2.0.v20060605.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.update.ui_3.2.0.v20060605.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.ui.forms_3.2.0.v20060602.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.debug.core_3.2.0.v20060605.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.debug.ui_3.2.0.v20060605.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.ui.editors_3.2.0.v20060605-1400.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.jdt.launching_3.2.0.v20060605.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.jdt.debug_3.2.0.v20060605/jdi.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.jdt.debug_3.2.0.v20060605/jdimodel.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.jdt.debug_3.2.0.v20060605/tools.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.compare_3.2.0.v20060605.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.team.ui_3.2.0.I200606051140.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.ui.navigator_3.2.0.I20060605-1400.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.ui.navigator.resources_3.2.0.I20060605-1400.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.ui.views.properties.tabbed_3.2.0.I20060605-1400.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.ltk.core.refactoring_3.2.0.v20060605-1400.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.ltk.ui.refactoring_3.2.0.v20060605-1400.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.jdt.core.manipulation_1.0.0.v20060605-1400.jar[?**/*] +#ADAPTER#ACCESS#com.ibm.wala.core/bin/[+com/ibm/wala/analysis/pointers/*;+com/ibm/wala/analysis/reflection/*;+com/ibm/wala/analysis/stackMachine/*;+com/ibm/wala/analysis/typeInference/*;+com/ibm/wala/cfg/*;+com/ibm/wala/cfg/cdg/*;+com/ibm/wala/classLoader/*;+com/ibm/wala/client/*;+com/ibm/wala/client/impl/*;+com/ibm/wala/core/plugin/*;+com/ibm/wala/dataflow/IFDS/*;+com/ibm/wala/dataflow/graph/*;+com/ibm/wala/dataflow/ssa/*;+com/ibm/wala/dynamic/*;+com/ibm/wala/emf/wrappers/*;+com/ibm/wala/escape/*;+com/ibm/wala/fixedpoint/impl/*;+com/ibm/wala/fixpoint/*;+com/ibm/wala/ipa/callgraph/*;+com/ibm/wala/ipa/callgraph/impl/*;+com/ibm/wala/ipa/callgraph/propagation/*;+com/ibm/wala/ipa/callgraph/propagation/cfa/*;+com/ibm/wala/ipa/callgraph/propagation/rta/*;+com/ibm/wala/ipa/cfg/*;+com/ibm/wala/ipa/cha/*;+com/ibm/wala/ipa/summaries/*;+com/ibm/wala/model/*;+com/ibm/wala/model/java/lang/*;+com/ibm/wala/properties/*;+com/ibm/wala/ssa/*;+com/ibm/wala/ssa/analysis/*;+com/ibm/wala/types/*;+com/ibm/wala/util/*;+com/ibm/wala/util/bytecode/*;+com/ibm/wala/util/collections/*;+com/ibm/wala/util/config/*;+com/ibm/wala/util/debug/*;+com/ibm/wala/util/graph/*;+com/ibm/wala/util/graph/impl/*;+com/ibm/wala/util/graph/traverse/*;+com/ibm/wala/util/heapTrace/*;+com/ibm/wala/util/intertionalization/*;+com/ibm/wala/util/intset/*;+com/ibm/wala/util/io/*;+com/ibm/wala/util/logging/*;+com/ibm/wala/util/math/*;+com/ibm/wala/util/perf/*;+com/ibm/wala/util/system/*;+com/ibm/wala/util/warnings/*;+com/ibm/wala/viz/*;?**/*] +#ADAPTER#ACCESS#com.ibm.wala.core/@dot[+com/ibm/wala/analysis/pointers/*;+com/ibm/wala/analysis/reflection/*;+com/ibm/wala/analysis/stackMachine/*;+com/ibm/wala/analysis/typeInference/*;+com/ibm/wala/cfg/*;+com/ibm/wala/cfg/cdg/*;+com/ibm/wala/classLoader/*;+com/ibm/wala/client/*;+com/ibm/wala/client/impl/*;+com/ibm/wala/core/plugin/*;+com/ibm/wala/dataflow/IFDS/*;+com/ibm/wala/dataflow/graph/*;+com/ibm/wala/dataflow/ssa/*;+com/ibm/wala/dynamic/*;+com/ibm/wala/emf/wrappers/*;+com/ibm/wala/escape/*;+com/ibm/wala/fixedpoint/impl/*;+com/ibm/wala/fixpoint/*;+com/ibm/wala/ipa/callgraph/*;+com/ibm/wala/ipa/callgraph/impl/*;+com/ibm/wala/ipa/callgraph/propagation/*;+com/ibm/wala/ipa/callgraph/propagation/cfa/*;+com/ibm/wala/ipa/callgraph/propagation/rta/*;+com/ibm/wala/ipa/cfg/*;+com/ibm/wala/ipa/cha/*;+com/ibm/wala/ipa/summaries/*;+com/ibm/wala/model/*;+com/ibm/wala/model/java/lang/*;+com/ibm/wala/properties/*;+com/ibm/wala/ssa/*;+com/ibm/wala/ssa/analysis/*;+com/ibm/wala/types/*;+com/ibm/wala/util/*;+com/ibm/wala/util/bytecode/*;+com/ibm/wala/util/collections/*;+com/ibm/wala/util/config/*;+com/ibm/wala/util/debug/*;+com/ibm/wala/util/graph/*;+com/ibm/wala/util/graph/impl/*;+com/ibm/wala/util/graph/traverse/*;+com/ibm/wala/util/heapTrace/*;+com/ibm/wala/util/intertionalization/*;+com/ibm/wala/util/intset/*;+com/ibm/wala/util/io/*;+com/ibm/wala/util/logging/*;+com/ibm/wala/util/math/*;+com/ibm/wala/util/perf/*;+com/ibm/wala/util/system/*;+com/ibm/wala/util/warnings/*;+com/ibm/wala/viz/*;?**/*] +#ADAPTER#ACCESS#com.ibm.wala.emf/bin/[+com/ibm/wala/ecore/common/*;+com/ibm/wala/ecore/common/impl/*;+com/ibm/wala/ecore/common/util/*;+com/ibm/wala/ecore/graph/*;+com/ibm/wala/ecore/graph/impl/*;+com/ibm/wala/ecore/graph/util/*;+com/ibm/wala/ecore/j2ee/scope/*;+com/ibm/wala/ecore/j2ee/scope/impl/*;+com/ibm/wala/ecore/j2ee/scope/util/*;+com/ibm/wala/ecore/java/*;+com/ibm/wala/ecore/java/callGraph/*;+com/ibm/wala/ecore/java/callGraph/impl/*;+com/ibm/wala/ecore/java/callGraph/util/*;+com/ibm/wala/ecore/java/impl/*;+com/ibm/wala/ecore/java/pointerAnalysis/*;+com/ibm/wala/ecore/java/pointerAnalysis/impl/*;+com/ibm/wala/ecore/java/pointerAnalysis/util/*;+com/ibm/wala/ecore/java/scope/*;+com/ibm/wala/ecore/java/scope/impl/*;+com/ibm/wala/ecore/java/scope/util/*;+com/ibm/wala/ecore/java/util/*;+com/ibm/wala/ecore/perf/*;+com/ibm/wala/ecore/perf/impl/*;+com/ibm/wala/ecore/perf/util/*;+com/ibm/wala/ecore/regex/*;+com/ibm/wala/ecore/regex/impl/*;+com/ibm/wala/ecore/regex/util/*;?**/*] +#ADAPTER#ACCESS#com.ibm.wala.emf/@dot[+com/ibm/wala/ecore/common/*;+com/ibm/wala/ecore/common/impl/*;+com/ibm/wala/ecore/common/util/*;+com/ibm/wala/ecore/graph/*;+com/ibm/wala/ecore/graph/impl/*;+com/ibm/wala/ecore/graph/util/*;+com/ibm/wala/ecore/j2ee/scope/*;+com/ibm/wala/ecore/j2ee/scope/impl/*;+com/ibm/wala/ecore/j2ee/scope/util/*;+com/ibm/wala/ecore/java/*;+com/ibm/wala/ecore/java/callGraph/*;+com/ibm/wala/ecore/java/callGraph/impl/*;+com/ibm/wala/ecore/java/callGraph/util/*;+com/ibm/wala/ecore/java/impl/*;+com/ibm/wala/ecore/java/pointerAnalysis/*;+com/ibm/wala/ecore/java/pointerAnalysis/impl/*;+com/ibm/wala/ecore/java/pointerAnalysis/util/*;+com/ibm/wala/ecore/java/scope/*;+com/ibm/wala/ecore/java/scope/impl/*;+com/ibm/wala/ecore/java/scope/util/*;+com/ibm/wala/ecore/java/util/*;+com/ibm/wala/ecore/perf/*;+com/ibm/wala/ecore/perf/impl/*;+com/ibm/wala/ecore/perf/util/*;+com/ibm/wala/ecore/regex/*;+com/ibm/wala/ecore/regex/impl/*;+com/ibm/wala/ecore/regex/util/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.emf.ecore_2.2.0.v200606271057.jar[+org/eclipse/emf/ecore/*;+org/eclipse/emf/ecore/impl/*;+org/eclipse/emf/ecore/plugin/*;+org/eclipse/emf/ecore/resource/*;+org/eclipse/emf/ecore/resource/impl/*;+org/eclipse/emf/ecore/util/*;+org/eclipse/emf/ecore/xml/namespace/*;+org/eclipse/emf/ecore/xml/namespace/impl/*;+org/eclipse/emf/ecore/xml/namespace/util/*;+org/eclipse/emf/ecore/xml/type/*;+org/eclipse/emf/ecore/xml/type/impl/*;+org/eclipse/emf/ecore/xml/type/internal/*;+org/eclipse/emf/ecore/xml/type/util/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.emf.common_2.2.0.v200606271057.jar[+org/eclipse/emf/common/*;+org/eclipse/emf/common/archive/*;+org/eclipse/emf/common/command/*;+org/eclipse/emf/common/notify/*;+org/eclipse/emf/common/notify/impl/*;+org/eclipse/emf/common/util/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.emf.ecore.xmi_2.2.0.v200606271057.jar[+org/eclipse/emf/ecore/xmi/*;+org/eclipse/emf/ecore/xmi/impl/*;+org/eclipse/emf/ecore/xmi/util/*;?**/*] +#ADAPTER#ACCESS#com.ibm.wala.shrike/bin/[+com/ibm/wala/shrike/bench/*;+com/ibm/wala/shrike/copywriter/*;+com/ibm/wala/shrike/tools/*;+com/ibm/wala/shrikeBT/*;+com/ibm/wala/shrikeBT/analysis/*;+com/ibm/wala/shrikeBT/info/*;+com/ibm/wala/shrikeBT/shrikeCT/*;+com/ibm/wala/shrikeBT/shrikeCT/tools/*;+com/ibm/wala/shrikeBT/tools/*;+com/ibm/wala/shrikeCT/*;?**/*] +#ADAPTER#ACCESS#com.ibm.wala.shrike/@dot[+com/ibm/wala/shrike/bench/*;+com/ibm/wala/shrike/copywriter/*;+com/ibm/wala/shrike/tools/*;+com/ibm/wala/shrikeBT/*;+com/ibm/wala/shrikeBT/analysis/*;+com/ibm/wala/shrikeBT/info/*;+com/ibm/wala/shrikeBT/shrikeCT/*;+com/ibm/wala/shrikeBT/shrikeCT/tools/*;+com/ibm/wala/shrikeBT/tools/*;+com/ibm/wala/shrikeCT/*;?**/*] diff --git a/com.ibm.wala.eclipse/launchers/wala.eclipse.launch b/com.ibm.wala.eclipse/launchers/wala.eclipse.launch new file mode 100644 index 000000000..a74fe9ccf --- /dev/null +++ b/com.ibm.wala.eclipse/launchers/wala.eclipse.launch @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/com.ibm.wala.eclipse/plugin.xml b/com.ibm.wala.eclipse/plugin.xml new file mode 100644 index 000000000..ad6ec0734 --- /dev/null +++ b/com.ibm.wala.eclipse/plugin.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + diff --git a/com.ibm.wala.eclipse/src/com/ibm/wala/eclipse/Activator.java b/com.ibm.wala.eclipse/src/com/ibm/wala/eclipse/Activator.java new file mode 100644 index 000000000..3f858a2d4 --- /dev/null +++ b/com.ibm.wala.eclipse/src/com/ibm/wala/eclipse/Activator.java @@ -0,0 +1,60 @@ +/******************************************************************************* + * 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.eclipse; + +import org.eclipse.ui.plugin.AbstractUIPlugin; +import org.osgi.framework.BundleContext; + +/** + * The activator class controls the plug-in life cycle + */ +public class Activator extends AbstractUIPlugin { + + // The plug-in ID + public static final String PLUGIN_ID = "com.ibm.wala.eclipse"; + + // The shared instance + private static Activator plugin; + + /** + * The constructor + */ + public Activator() { + plugin = this; + } + + /* + * (non-Javadoc) + * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext) + */ + public void start(BundleContext context) throws Exception { + super.start(context); + } + + /* + * (non-Javadoc) + * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext) + */ + public void stop(BundleContext context) throws Exception { + plugin = null; + super.stop(context); + } + + /** + * Returns the shared instance + * + * @return the shared instance + */ + public static Activator getDefault() { + return plugin; + } + +} diff --git a/com.ibm.wala.eclipse/src/com/ibm/wala/eclipse/cg/model/WalaCGModel.java b/com.ibm.wala.eclipse/src/com/ibm/wala/eclipse/cg/model/WalaCGModel.java new file mode 100644 index 000000000..93f8f200b --- /dev/null +++ b/com.ibm.wala.eclipse/src/com/ibm/wala/eclipse/cg/model/WalaCGModel.java @@ -0,0 +1,86 @@ +/******************************************************************************* + * 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.eclipse.cg.model; + +import java.util.Collection; + +import org.eclipse.jface.window.ApplicationWindow; + +import com.ibm.wala.ecore.java.scope.EJavaAnalysisScope; +import com.ibm.wala.emf.wrappers.EMFScopeWrapper; +import com.ibm.wala.emf.wrappers.JavaScopeUtil; +import com.ibm.wala.ipa.callgraph.CallGraph; +import com.ibm.wala.util.graph.Graph; +import com.ibm.wala.util.warnings.WalaException; +import com.ibm.wala.viz.SWTTreeViewer; + + +abstract public class WalaCGModel { + + /** + * Specifies the path of the jars files to be analyzed, each jar file separated by ';' + */ + protected String appJar; + + protected CallGraph callGraph; + + protected Collection roots; + + /** + * @param appJar Specifies the path of the jars files to be analyzed, each jar file separated by ';' + */ + public WalaCGModel(String appJar) { + this.appJar = appJar; + } + + /** + * @see CallGraphBuilderImpl.processImpl + * warning: this is bypassing emf and may cause problems + */ + public void buildGraph() throws WalaException { + EMFScopeWrapper escope = createAnalysisScope(); + callGraph = createCallGraph(escope); + roots = inferRoots(callGraph); + } + + public Graph getGraph() { + return callGraph; + } + + public Collection getRoots() { + return roots; + } + + /** + * @see SWTCallGraph + */ + protected EMFScopeWrapper createAnalysisScope() throws WalaException { + EJavaAnalysisScope escope = JavaScopeUtil.makeAnalysisScope(appJar); + + escope.setExclusionFileName("J2SEClassHierarchyExclusions.xml"); + + // generate a DOMO-consumable wrapper around the incoming scope object + EMFScopeWrapper scope = EMFScopeWrapper.generateScope(escope); + return scope; + } + + abstract protected CallGraph createCallGraph(EMFScopeWrapper escope) throws WalaException; + + abstract protected Collection inferRoots(CallGraph cg) throws WalaException; + + public ApplicationWindow makeUI(Graph graph, Collection roots) throws WalaException { + final SWTTreeViewer v = new SWTTreeViewer(); + v.setGraphInput(graph); + v.setRootsInput(roots); + v.run(); + return v.getApplicationWindow(); + } +} diff --git a/com.ibm.wala.eclipse/src/com/ibm/wala/eclipse/cg/model/WalaCGModelWithMain.java b/com.ibm.wala.eclipse/src/com/ibm/wala/eclipse/cg/model/WalaCGModelWithMain.java new file mode 100644 index 000000000..c71432d00 --- /dev/null +++ b/com.ibm.wala.eclipse/src/com/ibm/wala/eclipse/cg/model/WalaCGModelWithMain.java @@ -0,0 +1,67 @@ +/******************************************************************************* + * 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.eclipse.cg.model; + +import java.util.Collection; + +import com.ibm.wala.emf.wrappers.EMFScopeWrapper; +import com.ibm.wala.ipa.callgraph.AnalysisOptions; +import com.ibm.wala.ipa.callgraph.CallGraph; +import com.ibm.wala.ipa.callgraph.Entrypoints; +import com.ibm.wala.ipa.callgraph.impl.Util; +import com.ibm.wala.ipa.cha.ClassHierarchy; +import com.ibm.wala.util.graph.InferGraphRootsImpl; +import com.ibm.wala.util.warnings.WalaException; +import com.ibm.wala.util.warnings.WarningSet; + +/** + * + * @author aying + */ +public class WalaCGModelWithMain extends WalaCGModel { + + /* + * @see WalaCGModel + */ + public WalaCGModelWithMain(String appJar) { + super(appJar); + } + + /** + * @see SWTCallGraph + */ + @Override + protected CallGraph createCallGraph(EMFScopeWrapper scope) throws WalaException { + + // TODO: return the warning set (need a CAPA type) + // invoke DOMO to build a DOMO class hierarchy object + WarningSet warnings = new WarningSet(); + ClassHierarchy cha = ClassHierarchy.make(scope, warnings); + + Entrypoints entrypoints = com.ibm.wala.ipa.callgraph.impl.Util.makeMainEntrypoints(scope, cha); + AnalysisOptions options = new AnalysisOptions(scope, entrypoints); + + // // + // build the call graph + // // + com.ibm.wala.ipa.callgraph.CallGraphBuilder builder = Util.makeZeroCFABuilder(options, cha, scope, warnings, null, null); + CallGraph cg = builder.makeCallGraph(options); + return cg; + } + + /** + * @see SWTCallGraph + */ + @Override + protected Collection inferRoots(CallGraph cg) throws WalaException { + return InferGraphRootsImpl.inferRoots(cg); + } +} diff --git a/com.ibm.wala.eclipse/src/com/ibm/wala/eclipse/cg/views/CGContentProvider.java b/com.ibm.wala.eclipse/src/com/ibm/wala/eclipse/cg/views/CGContentProvider.java new file mode 100644 index 000000000..9f12407ea --- /dev/null +++ b/com.ibm.wala.eclipse/src/com/ibm/wala/eclipse/cg/views/CGContentProvider.java @@ -0,0 +1,117 @@ +/******************************************************************************* + * 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.eclipse.cg.views; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.Map; + +import org.eclipse.jdt.core.IJavaElement; +import org.eclipse.jface.viewers.ITreeContentProvider; +import org.eclipse.jface.viewers.Viewer; + +import com.ibm.wala.ipa.callgraph.CGNode; +import com.ibm.wala.util.debug.Assertions; +import com.ibm.wala.util.graph.Graph; + +/** + * @author sfink + * @author aying + * + * Simple wrapper around an EObjectGraph to provide content for a tree viewer. + */ +public class CGContentProvider implements ITreeContentProvider { + + protected Graph graph; + + protected Collection roots; + + protected Map capaNodeIdToJavaElement = null; + + public CGContentProvider(Graph g, Collection roots, Map capaNodeIdToJavaElement) { + this.graph = g; + this.roots = roots; + this.capaNodeIdToJavaElement = capaNodeIdToJavaElement; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.viewers.IContentProvider#dispose() + */ + public void dispose() { + // do nothing for now + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.viewers.IContentProvider#inputChanged(org.eclipse.jface.viewers.Viewer, + * java.lang.Object, java.lang.Object) + */ + public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { + // for now do nothing, since we're not dealing with listeners + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.viewers.ITreeContentProvider#getChildren(java.lang.Object) + */ + public Object[] getChildren(Object parentElement) { + + Collection result = new ArrayList(); + for (Iterator it = graph.getSuccNodes((CGNode) parentElement); it.hasNext();) { + CGNode capaNode = (CGNode) it.next(); + result.add(capaNode); + } + return result.toArray(); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.viewers.ITreeContentProvider#getParent(java.lang.Object) + */ + public Object getParent(Object element) { + // TODO Auto-generated method stub + Assertions.UNREACHABLE(); + return null; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.viewers.ITreeContentProvider#hasChildren(java.lang.Object) + */ + public boolean hasChildren(Object element) { + return graph.getSuccNodeCount((CGNode) element) > 0; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.viewers.IStructuredContentProvider#getElements(java.lang.Object) + */ + public Object[] getElements(Object inputElement) { + Object[] firstLevelNodes = new Object[roots.size()]; + Iterator rootIt = roots.iterator(); + int i = 0; + while (rootIt.hasNext()) { + CGNode capaNode = (CGNode) rootIt.next(); + firstLevelNodes[i++] = capaNode; + } + + return firstLevelNodes; + } +} diff --git a/com.ibm.wala.eclipse/src/com/ibm/wala/eclipse/cg/views/CGJavaLabelProvider.java b/com.ibm.wala.eclipse/src/com/ibm/wala/eclipse/cg/views/CGJavaLabelProvider.java new file mode 100644 index 000000000..a218faac2 --- /dev/null +++ b/com.ibm.wala.eclipse/src/com/ibm/wala/eclipse/cg/views/CGJavaLabelProvider.java @@ -0,0 +1,104 @@ +package com.ibm.wala.eclipse.cg.views; + +import java.util.Map; + +import org.eclipse.jdt.core.IJavaElement; +import org.eclipse.jdt.internal.ui.JavaPlugin; +import org.eclipse.jdt.internal.ui.JavaPluginImages; +import org.eclipse.jdt.internal.ui.viewsupport.JavaElementImageProvider; +import org.eclipse.jdt.ui.JavaElementImageDescriptor; +import org.eclipse.jdt.ui.JavaElementLabelProvider; +import org.eclipse.jface.viewers.LabelProvider; +import org.eclipse.swt.graphics.Image; + +import com.ibm.wala.ipa.callgraph.CGNode; + +public class CGJavaLabelProvider extends LabelProvider { + + private Map capaNodeIdToJavaElement; + private JavaElementLabelProvider javaEltProvider; + + + public CGJavaLabelProvider(Map capaNodeIdToJavaElement) { + super(); + this.capaNodeIdToJavaElement = capaNodeIdToJavaElement; + javaEltProvider = new JavaElementLabelProvider(JavaElementLabelProvider.SHOW_PARAMETERS | + JavaElementLabelProvider.SHOW_OVERLAY_ICONS | + JavaElementLabelProvider.SHOW_POST_QUALIFIED | + JavaElementLabelProvider.SHOW_RETURN_TYPE); + } + + /* + * (non-Javadoc) + * @see org.eclipse.jface.viewers.LabelProvider#getText(java.lang.Object) + */ + @Override + public String getText(Object element) { + CGNode capaNode = (CGNode)element; + + IJavaElement jdtElt = capaNodeIdToJavaElement.get(capaNode.getGraphNodeId()); + if( jdtElt != null && jdtElt.exists() ) { + return javaEltProvider.getText(jdtElt); + } + else { + return getWalaText(capaNode); + } + } + + private String getWalaText(CGNode capaNode) { + + String className = capaNode.getMethod().getDeclaringClass().getName().toString().substring(1); + + String methodName = capaNode.getMethod().getName().toString(); + if( methodName.equals("")) { + methodName = className.substring(className.lastIndexOf('/')+1, className.length()); + } + + String params = ""; + for( int i=0; i < capaNode.getMethod().getNumberOfParameters(); i++) { + params +=capaNode.getMethod().getParameterType(i).getName() + ";"; + } + + return methodName + "(" + params + ")" + " - " + className; + } + + /* + * (non-Javadoc) + * @see org.eclipse.jface.viewers.LabelProvider#getImage(java.lang.Object) + */ + @Override + public Image getImage(Object element) { + + // get the image depending on the element + CGNode capaNode = (CGNode)element; + IJavaElement jdtElt = capaNodeIdToJavaElement.get(capaNode.getGraphNodeId()); + Image image = null; + if( jdtElt == null ) { + image = getCapaImage(); + } + else if( jdtElt.exists() ){ + image = javaEltProvider.getImage(jdtElt); + } + else { + image = getWarningImage(); + } + return image; + } + + private Image getCapaImage() { + return JavaPlugin.getImageDescriptorRegistry().get( + new JavaElementImageDescriptor( + JavaPluginImages.DESC_OBJS_CFILE, + 0, + JavaElementImageProvider.BIG_SIZE)); + } + + private Image getWarningImage() { + + return JavaPlugin.getImageDescriptorRegistry().get( + new JavaElementImageDescriptor( + JavaPluginImages.DESC_OBJS_REFACTORING_WARNING, + 0, + JavaElementImageProvider.BIG_SIZE)); + } +} diff --git a/com.ibm.wala.eclipse/src/com/ibm/wala/eclipse/cg/views/CGView.java b/com.ibm.wala.eclipse/src/com/ibm/wala/eclipse/cg/views/CGView.java new file mode 100644 index 000000000..481bdce74 --- /dev/null +++ b/com.ibm.wala.eclipse/src/com/ibm/wala/eclipse/cg/views/CGView.java @@ -0,0 +1,156 @@ +/******************************************************************************* + * 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.eclipse.cg.views; + +import java.util.Collection; +import java.util.Map; + +import org.eclipse.core.resources.IFile; +import org.eclipse.jdt.core.IJavaElement; +import org.eclipse.jdt.core.IJavaProject; +import org.eclipse.jdt.core.JavaModelException; +import org.eclipse.jdt.ui.JavaUI; +import org.eclipse.jface.viewers.IOpenListener; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.ITreeSelection; +import org.eclipse.jface.viewers.OpenEvent; +import org.eclipse.jface.viewers.TreeViewer; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.ui.PartInitException; +import org.eclipse.ui.part.ViewPart; + +import com.ibm.wala.eclipse.cg.model.WalaCGModel; +import com.ibm.wala.eclipse.cg.model.WalaCGModelWithMain; +import com.ibm.wala.eclipse.util.CapaToJavaEltConverter; +import com.ibm.wala.eclipse.util.JdtUtil; +import com.ibm.wala.ipa.callgraph.CGNode; +import com.ibm.wala.util.graph.Graph; +import com.ibm.wala.util.warnings.WalaException; + +/** + * This sample class demonstrates how to plug-in a new workbench view. The view + * shows data obtained from the model. The sample creates a dummy model on the + * fly, but a real implementation would connect to the model available either in + * this or another plug-in (e.g. the workspace). The view is connected to the + * model using a content provider. + *

                              + * The view uses a label provider to define how model objects should be + * presented in the view. Each view can present the same model objects using + * different labels and icons, if needed. Alternatively, a single label provider + * can be shared between views in order to ensure that objects of the same type + * are presented in the same way everywhere. + *

                              + * + * @author aying + */ + +public class CGView extends ViewPart { + + public static final String ID = "com.ibm.wala.eclipse.views.cfg.CGView"; + + private TreeViewer viewer; + + /** + * The constructor. + */ + public CGView() throws JavaModelException { + } + + /** + * This is a callback that will allow us to create the viewer and initialize + * it. + */ + public void createPartControl(Composite parent) { + IFile selectedJar = getSelectedJar(); + if( selectedJar != null ) { + createViewer(parent, selectedJar); + } + } + + private IFile getSelectedJar() { + ISelection currentSelection = getSite().getWorkbenchWindow().getSelectionService().getSelection(); + + if (currentSelection instanceof IStructuredSelection) { + Object selected = ((IStructuredSelection) currentSelection).getFirstElement(); + if (selected instanceof IFile && ((IFile) selected).getFileExtension().equals("jar")) { + return (IFile) selected; + } + } + return null; + } + + private void createViewer(Composite parent, IFile jarFile) { + try { + // get the selected jar file + String applicationJar = jarFile.getRawLocation().toString(); + IJavaProject project = JdtUtil.getJavaProject(jarFile); + + // compute the call graph + WalaCGModel model = new WalaCGModelWithMain(applicationJar); + model.buildGraph(); + Collection roots = model.getRoots(); + Graph graph = model.getGraph(); + + // convert call graph nodes to Eclipse JDT elements + final Map capaNodeIdToJavaElement = CapaToJavaEltConverter.convert( + model.getGraph(), project); + + // create the tree view + viewer = new TreeViewer(parent); + viewer.setContentProvider(new CGContentProvider(graph, roots, capaNodeIdToJavaElement)); + viewer.setLabelProvider(new CGJavaLabelProvider(capaNodeIdToJavaElement)); + viewer.setInput(getViewSite()); + viewer.addOpenListener(new IOpenListener() { + // open the file when element in the tree is clicked + public void open(OpenEvent e) { + ISelection sel = e.getSelection(); + if (sel instanceof ITreeSelection) { + ITreeSelection treeSel = (ITreeSelection) sel; + Object selectedElt = treeSel.getFirstElement(); + if (selectedElt instanceof CGNode) { + try { + CGNode capaNode = (CGNode) selectedElt; + IJavaElement jdtElt = capaNodeIdToJavaElement.get(capaNode.getGraphNodeId()); + if (jdtElt != null) { + JavaUI.revealInEditor(JavaUI.openInEditor(jdtElt), jdtElt); + } + } catch (PartInitException e1) { + // TODO Auto-generated catch block + e1.printStackTrace(); + } catch (JavaModelException e1) { + // TODO Auto-generated catch block + e1.printStackTrace(); + } + } + } + } + }); + } catch (JavaModelException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (WalaException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + + /** + * Passing the focus request to the viewer's control. + */ + public void setFocus() { + if( viewer != null && viewer.getControl() != null ) { + viewer.getControl().setFocus(); + } + } + +} \ No newline at end of file diff --git a/com.ibm.wala.eclipse/src/com/ibm/wala/eclipse/cg/views/SelectCapaCGAction.java b/com.ibm.wala.eclipse/src/com/ibm/wala/eclipse/cg/views/SelectCapaCGAction.java new file mode 100644 index 000000000..7ac61acd5 --- /dev/null +++ b/com.ibm.wala.eclipse/src/com/ibm/wala/eclipse/cg/views/SelectCapaCGAction.java @@ -0,0 +1,70 @@ +/******************************************************************************* + * 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.eclipse.cg.views; + +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.ui.IActionDelegate; +import org.eclipse.ui.IObjectActionDelegate; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.IWorkbenchPart; +import org.eclipse.ui.PartInitException; +import org.eclipse.ui.PlatformUI; + +public class SelectCapaCGAction implements IObjectActionDelegate { + + private ISelection currentSelection; + + /** + * Constructor for SelectionAction + */ + public SelectCapaCGAction() { + super(); + } + + /** + * @see IObjectActionDelegate#setActivePart(IAction, IWorkbenchPart) + */ + public void setActivePart(IAction action, IWorkbenchPart targetPart) { + } + + /** + * @see IActionDelegate#run(IAction) + */ + public void run(IAction action) { + if( currentSelection instanceof IStructuredSelection ) { + + IWorkbenchPage page = PlatformUI.getWorkbench().getWorkbenchWindows()[0].getPages()[0]; + CGView view = (CGView)page.findView(CGView.ID); + + if(view==null) { + try { +// IFile jarFile = (IFile)((IStructuredSelection)currentSelection).getFirstElement(); +// String applicationJar = jarFile.getRawLocation().toString(); +// String applicationJar2 = jarFile.getFullPath().toString(); + view = (CGView)page.showView(CGView.ID); + } catch (PartInitException e) { + e.printStackTrace(); + } + } + + } + } + + /** + * @see IActionDelegate#selectionChanged(IAction, ISelection) + */ + public void selectionChanged(IAction action, ISelection selection) { + currentSelection = selection; + } + +} diff --git a/com.ibm.wala.eclipse/src/com/ibm/wala/eclipse/util/CapaToJavaEltConverter.java b/com.ibm.wala.eclipse/src/com/ibm/wala/eclipse/util/CapaToJavaEltConverter.java new file mode 100644 index 000000000..239724cd2 --- /dev/null +++ b/com.ibm.wala.eclipse/src/com/ibm/wala/eclipse/util/CapaToJavaEltConverter.java @@ -0,0 +1,183 @@ +/******************************************************************************* + * 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.eclipse.util; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import org.eclipse.jdt.core.ICompilationUnit; +import org.eclipse.jdt.core.IJavaElement; +import org.eclipse.jdt.core.IJavaProject; +import org.eclipse.jdt.core.IMethod; +import org.eclipse.jdt.core.IType; +import org.eclipse.jdt.core.JavaModelException; +import org.eclipse.jdt.core.Signature; + +import com.ibm.wala.ipa.callgraph.CGNode; +import com.ibm.wala.types.TypeReference; +import com.ibm.wala.util.graph.Graph; + +public class CapaToJavaEltConverter { + + /** + * =Jakarta Commons CLI/test convert(Graph graph, IJavaProject javaProject) throws JavaModelException { + + Map capaNodeToJdt = new HashMap(); + Iterator capaIt = graph.iterateNodes(); + List jdtClasses = getJdtClasses(javaProject); + + while (capaIt.hasNext()) { + CGNode capaMethod = (CGNode) capaIt.next(); + String capaClassName = getLongClassName(capaMethod); + + Iterator jdtClassesIt = jdtClasses.iterator(); + while (jdtClassesIt.hasNext()) { + IType jdtClass = (IType) jdtClassesIt.next(); + + String jdtClassName = getLongClassName(jdtClass); + + if (capaClassName.equals(jdtClassName)) { + + String capaMethodName = getMethodName(capaMethod); + String[] capaParamTypes = getParamTypes(capaMethod); + IMethod method = jdtClass.getMethod(capaMethodName, capaParamTypes); + + capaNodeToJdt.put(capaMethod.getGraphNodeId(), method); + } + } + } + return capaNodeToJdt; + } + + private static List getJdtClasses(IJavaProject javaProject) { + List result = new ArrayList(); + List cus = JdtUtil.getJavaCompilationUnits(javaProject); + for (ICompilationUnit cu : cus) { + IType[] types = JdtUtil.getClasses(cu); + for (IType type : types) { + result.add(type); + } + } + return result; + } + + public static String getLongClassName(CGNode capaMethod) { + String capaTypeName = capaMethod.getMethod().getDeclaringClass().getName().toString().substring(1); + return capaTypeName; + } + + public static String getLongClassName(IType jdtClass) { + String jdtTypeName = jdtClass.getFullyQualifiedName(); + return jdtTypeName.replace('.', '/'); + } + + @SuppressWarnings("unused") + private static boolean hasSameMethodName(CGNode capaMethod, IMethod jdtMethod) { + String capaMethodName = getMethodName(capaMethod); + String jdtMethodName = getMethodName(jdtMethod); + return capaMethodName.equals(jdtMethodName); + } + + private static String getMethodName(CGNode capaMethod) { + String capaMethodName = capaMethod.getMethod().getName().toString(); + if (capaMethodName.equals("")) { + capaMethodName = capaMethod.getMethod().getDeclaringClass().getName().toString().substring( + capaMethod.getMethod().getDeclaringClass().getName().toString().lastIndexOf('/') + 1, + capaMethod.getMethod().getDeclaringClass().getName().toString().length()); + } + return capaMethodName; + } + + private static String getMethodName(IMethod jdtMethod) { + return jdtMethod.getElementName(); + } + + private static String[] getParamTypes(CGNode capaMethod) { + + List capaParams = getParams(capaMethod); + Iterator capaParamsIt = capaParams.iterator(); + String[] result = new String[capaParams.size()]; + + // check the type of each param + for (int i = 0; capaParamsIt.hasNext(); i++) { + + TypeReference capaParamType = (TypeReference) capaParamsIt.next(); + String type = ""; + String arrayType = ""; + + // TODO should handle multi-dimenional arrays + // this assumes is 1-D array + if (capaParamType.isArrayType()) { + arrayType = "[]"; + + // get the array element + capaParamType = capaParamType.getArrayElementType(); + } + + if (capaParamType.isPrimitiveType()) { + String capaType = capaParamType.getName().toString(); + if (capaType.equals("C")) + type = "char"; + else if (capaType.equals("Z")) + type = "boolean"; + else if (capaType.equals("I")) + type = "int"; + else if (capaType.equals("B")) + type = "byte"; + else if (capaType.equals("D")) + type = "double"; + else if (capaType.equals("F")) + type = "float"; + else if (capaType.equals("J")) + type = "long"; + else if (capaType.equals("S")) + type = "short"; + } else if (capaParamType.isClassType()) { + type = capaParamType.getName().toString().substring(capaParamType.getName().getPackage().length() + 2, + capaParamType.getName().toString().length()); + + } + result[i] = Signature.createTypeSignature(type + arrayType, false); + } + return result; + } + + private static List getParams(CGNode node) { + int nbrParamsIncludingThisRef = node.getMethod().getNumberOfParameters(); + List result = new ArrayList(nbrParamsIncludingThisRef); + int startParamNbr = 0; + if (node.getMethod().isStatic() || node.getMethod().isClinit()) { + startParamNbr = 0; + } else { + startParamNbr = 1; + } + + for (int i = startParamNbr; i < nbrParamsIncludingThisRef; i++) { + result.add(node.getMethod().getParameterType(i)); + } + return result; + } + + @SuppressWarnings("unused") + private static String[] getSimpleParamTypes(IMethod jdtMethod) { + String[] paramTypes = jdtMethod.getParameterTypes(); + String[] humanReadableTypes = new String[paramTypes.length]; + for (String paramType : paramTypes) { + JdtUtil.getHumanReadableType(paramType); + } + return humanReadableTypes; + } +} diff --git a/com.ibm.wala.eclipse/src/com/ibm/wala/eclipse/util/JdtUtil.java b/com.ibm.wala.eclipse/src/com/ibm/wala/eclipse/util/JdtUtil.java new file mode 100644 index 000000000..8d6bd1ef8 --- /dev/null +++ b/com.ibm.wala.eclipse/src/com/ibm/wala/eclipse/util/JdtUtil.java @@ -0,0 +1,188 @@ +/******************************************************************************* + * 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.eclipse.util; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IWorkspaceRoot; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.jdt.core.ICompilationUnit; +import org.eclipse.jdt.core.IJavaElement; +import org.eclipse.jdt.core.IJavaModel; +import org.eclipse.jdt.core.IJavaProject; +import org.eclipse.jdt.core.IMethod; +import org.eclipse.jdt.core.IPackageDeclaration; +import org.eclipse.jdt.core.IPackageFragment; +import org.eclipse.jdt.core.IPackageFragmentRoot; +import org.eclipse.jdt.core.IType; +import org.eclipse.jdt.core.JavaCore; +import org.eclipse.jdt.core.JavaModelException; +import org.eclipse.jdt.core.Signature; +import org.eclipse.jdt.internal.core.JarPackageFragmentRoot; + +/** + * Convenience methods to get information from JDT IJavaElement model. + * + * @author aying + */ +public class JdtUtil { + + public static String getFilePath(IJavaElement javaElt) { + String filePath = javaElt.getPath().toString(); + return filePath; + } + + public static String getPackageName(ICompilationUnit cu) { + try { + IPackageDeclaration[] pkgDecl = cu.getPackageDeclarations(); + + // TODO: handle default package? + if( pkgDecl != null && pkgDecl.length > 0 ) { + String packageName = pkgDecl[0].getElementName(); + return packageName; + } + } catch (JavaModelException e) { + + } + return ""; + + } + + public static String getFullyQualifiedClassName(IType type) { + ICompilationUnit cu = (ICompilationUnit)type.getParent(); + String packageName = getPackageName(cu); + String className = type.getElementName(); + String fullyQName = packageName + "." + className; + return fullyQName; + } + + public static String getClassName(IType type) { + String className = type.getElementName(); + return className; + } + + public static String getMethodSignature(IMethod method) { + try { + String methodParamReturnInfo = method.getSignature(); + String methodName = method.getElementName(); + String methodSignature = methodName + " " + methodParamReturnInfo; + return methodSignature; + } catch (JavaModelException e) { + } + return ""; + } + + /** + * Return a unique string representing the specified + * Java element across projects in the workspace. + * The returned string can be used as a handle to create + * JavaElement by 'JavaCore.create(String)' + * + * For example, suppose we have the method + * 'fooPackage.barPackage.FooClass.fooMethod(int)' + * which is in the 'FooProject' and source folder 'src' + * the handle would be + * '=FooProject/src getJavaCompilationUnits(IJavaProject javaProject) { + List cuResult = new ArrayList(); + try { + if( javaProject.hasChildren() ) { + IPackageFragmentRoot[] packFragRoots = javaProject.getPackageFragmentRoots(); + for (int i = 0; i < packFragRoots.length; i++) { + IPackageFragmentRoot packFragRoot = packFragRoots[i]; + if ( packFragRoot instanceof JarPackageFragmentRoot == false + && packFragRoot.hasChildren()) { + IJavaElement[] packFrags = packFragRoot.getChildren(); + for (int j = 0; j < packFrags.length; j++) { + ICompilationUnit[] cus = ((IPackageFragment) packFrags[j]).getCompilationUnits(); + if (cus != null) { + Collections.addAll(cuResult, cus); + } + } + } + } + } + } catch (JavaModelException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + return cuResult; + } + + public static IType[] getClasses(ICompilationUnit cu) { + try { + return cu.getAllTypes(); + } + catch(JavaModelException e) { + + } + return null; + } + + public static IJavaProject getProject(IJavaElement javaElt) { + IJavaProject javaProject = javaElt.getJavaProject(); + return javaProject; + } + + public static String getProjectName(IJavaProject javaProject) { + return javaProject.getElementName(); + } + + + /** + * @param typeSignature Some of the type signatures examples are "QString;" (String) + * and "I" (int) + * The type signatures may be either unresolved (for source types) + * or resolved (for binary types), and either basic (for basic types) + * or rich (for parameterized types). See {@link Signature} for details. + */ + public static String getHumanReadableType(String typeSignature) { + String simpleName = Signature.getSignatureSimpleName(typeSignature); + return simpleName; + } + + + public static IJavaProject getJavaProject(IFile appJar) { + String projectName = appJar.getProject().getName(); + IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot(); + IJavaModel javaModel = JavaCore.create(workspaceRoot); + IJavaProject javaProject = javaModel.getJavaProject(projectName); + return javaProject; + } + + public static IJavaProject getHelloWorldProject() { + IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot(); + IJavaModel javaModel = JavaCore.create(workspaceRoot); + IJavaProject helloWorldProject = javaModel.getJavaProject("HelloWorld"); + return helloWorldProject; + } + + public static IFile getHelloWorldJar() { + IJavaProject project = getHelloWorldProject(); + IFile helloWorldJar = project.getProject().getFile("helloWorld.jar"); + return helloWorldJar; + } +} diff --git a/com.ibm.wala.emf/.classpath b/com.ibm.wala.emf/.classpath new file mode 100644 index 000000000..4a32a6643 --- /dev/null +++ b/com.ibm.wala.emf/.classpath @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/com.ibm.wala.emf/.project b/com.ibm.wala.emf/.project new file mode 100644 index 000000000..52ba4a524 --- /dev/null +++ b/com.ibm.wala.emf/.project @@ -0,0 +1,28 @@ + + + com.ibm.wala.emf + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/com.ibm.wala.emf/.settings/org.eclipse.jdt.core.prefs b/com.ibm.wala.emf/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 000000000..2dee6f2c5 --- /dev/null +++ b/com.ibm.wala.emf/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,12 @@ +#Thu Oct 19 11:13:23 EDT 2006 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.4 +org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve +org.eclipse.jdt.core.compiler.compliance=1.4 +org.eclipse.jdt.core.compiler.debug.lineNumber=generate +org.eclipse.jdt.core.compiler.debug.localVariable=generate +org.eclipse.jdt.core.compiler.debug.sourceFile=generate +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=warning +org.eclipse.jdt.core.compiler.source=1.4 diff --git a/com.ibm.wala.emf/.settings/org.eclipse.jdt.ui.prefs b/com.ibm.wala.emf/.settings/org.eclipse.jdt.ui.prefs new file mode 100644 index 000000000..7cd59575f --- /dev/null +++ b/com.ibm.wala.emf/.settings/org.eclipse.jdt.ui.prefs @@ -0,0 +1,3 @@ +#Thu Oct 19 11:13:23 EDT 2006 +eclipse.preferences.version=1 +internal.default.compliance=user diff --git a/com.ibm.wala.emf/META-INF/MANIFEST.MF b/com.ibm.wala.emf/META-INF/MANIFEST.MF new file mode 100644 index 000000000..a8119a7bf --- /dev/null +++ b/com.ibm.wala.emf/META-INF/MANIFEST.MF @@ -0,0 +1,40 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: WALA EMF structures +Bundle-SymbolicName: com.ibm.wala.emf; singleton:=true +Bundle-Version: 1.0.0 +Bundle-ClassPath: . +Bundle-Vendor: WALA +Bundle-Localization: plugin +Require-Bundle: org.eclipse.core.runtime;visibility:=reexport, + org.eclipse.emf.ecore;visibility:=reexport, + org.eclipse.emf.ecore.xmi;visibility:=reexport +Eclipse-LazyStart: true +Export-Package: ., + com.ibm.wala.ecore.common, + com.ibm.wala.ecore.common.impl, + com.ibm.wala.ecore.common.util, + com.ibm.wala.ecore.graph, + com.ibm.wala.ecore.graph.impl, + com.ibm.wala.ecore.graph.util, + com.ibm.wala.ecore.j2ee.scope, + com.ibm.wala.ecore.j2ee.scope.impl, + com.ibm.wala.ecore.j2ee.scope.util, + com.ibm.wala.ecore.java, + com.ibm.wala.ecore.java.callGraph, + com.ibm.wala.ecore.java.callGraph.impl, + com.ibm.wala.ecore.java.callGraph.util, + com.ibm.wala.ecore.java.impl, + com.ibm.wala.ecore.java.pointerAnalysis, + com.ibm.wala.ecore.java.pointerAnalysis.impl, + com.ibm.wala.ecore.java.pointerAnalysis.util, + com.ibm.wala.ecore.java.scope, + com.ibm.wala.ecore.java.scope.impl, + com.ibm.wala.ecore.java.scope.util, + com.ibm.wala.ecore.java.util, + com.ibm.wala.ecore.perf, + com.ibm.wala.ecore.perf.impl, + com.ibm.wala.ecore.perf.util, + com.ibm.wala.ecore.regex, + com.ibm.wala.ecore.regex.impl, + com.ibm.wala.ecore.regex.util diff --git a/com.ibm.wala.emf/build.properties b/com.ibm.wala.emf/build.properties new file mode 100644 index 000000000..bddf3d191 --- /dev/null +++ b/com.ibm.wala.emf/build.properties @@ -0,0 +1,13 @@ +# +# +# +# $Id$ + +bin.includes = .,\ + META-INF/,\ + plugin.xml,\ + plugin.properties +jars.compile.order = . +source.. = src/,\ + models/ +output.. = bin/ diff --git a/com.ibm.wala.emf/build.xml b/com.ibm.wala.emf/build.xml new file mode 100644 index 000000000..b2a70b391 --- /dev/null +++ b/com.ibm.wala.emf/build.xml @@ -0,0 +1,187 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/com.ibm.wala.emf/com.ibm.wala.emf/.classpath b/com.ibm.wala.emf/com.ibm.wala.emf/.classpath new file mode 100644 index 000000000..4a32a6643 --- /dev/null +++ b/com.ibm.wala.emf/com.ibm.wala.emf/.classpath @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/com.ibm.wala.emf/com.ibm.wala.emf/.project b/com.ibm.wala.emf/com.ibm.wala.emf/.project new file mode 100644 index 000000000..52ba4a524 --- /dev/null +++ b/com.ibm.wala.emf/com.ibm.wala.emf/.project @@ -0,0 +1,28 @@ + + + com.ibm.wala.emf + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/com.ibm.wala.emf/com.ibm.wala.emf/.settings/org.eclipse.jdt.core.prefs b/com.ibm.wala.emf/com.ibm.wala.emf/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 000000000..2dee6f2c5 --- /dev/null +++ b/com.ibm.wala.emf/com.ibm.wala.emf/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,12 @@ +#Thu Oct 19 11:13:23 EDT 2006 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.4 +org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve +org.eclipse.jdt.core.compiler.compliance=1.4 +org.eclipse.jdt.core.compiler.debug.lineNumber=generate +org.eclipse.jdt.core.compiler.debug.localVariable=generate +org.eclipse.jdt.core.compiler.debug.sourceFile=generate +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=warning +org.eclipse.jdt.core.compiler.source=1.4 diff --git a/com.ibm.wala.emf/com.ibm.wala.emf/.settings/org.eclipse.jdt.ui.prefs b/com.ibm.wala.emf/com.ibm.wala.emf/.settings/org.eclipse.jdt.ui.prefs new file mode 100644 index 000000000..7cd59575f --- /dev/null +++ b/com.ibm.wala.emf/com.ibm.wala.emf/.settings/org.eclipse.jdt.ui.prefs @@ -0,0 +1,3 @@ +#Thu Oct 19 11:13:23 EDT 2006 +eclipse.preferences.version=1 +internal.default.compliance=user diff --git a/com.ibm.wala.emf/com.ibm.wala.emf/META-INF/MANIFEST.MF b/com.ibm.wala.emf/com.ibm.wala.emf/META-INF/MANIFEST.MF new file mode 100644 index 000000000..a8119a7bf --- /dev/null +++ b/com.ibm.wala.emf/com.ibm.wala.emf/META-INF/MANIFEST.MF @@ -0,0 +1,40 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: WALA EMF structures +Bundle-SymbolicName: com.ibm.wala.emf; singleton:=true +Bundle-Version: 1.0.0 +Bundle-ClassPath: . +Bundle-Vendor: WALA +Bundle-Localization: plugin +Require-Bundle: org.eclipse.core.runtime;visibility:=reexport, + org.eclipse.emf.ecore;visibility:=reexport, + org.eclipse.emf.ecore.xmi;visibility:=reexport +Eclipse-LazyStart: true +Export-Package: ., + com.ibm.wala.ecore.common, + com.ibm.wala.ecore.common.impl, + com.ibm.wala.ecore.common.util, + com.ibm.wala.ecore.graph, + com.ibm.wala.ecore.graph.impl, + com.ibm.wala.ecore.graph.util, + com.ibm.wala.ecore.j2ee.scope, + com.ibm.wala.ecore.j2ee.scope.impl, + com.ibm.wala.ecore.j2ee.scope.util, + com.ibm.wala.ecore.java, + com.ibm.wala.ecore.java.callGraph, + com.ibm.wala.ecore.java.callGraph.impl, + com.ibm.wala.ecore.java.callGraph.util, + com.ibm.wala.ecore.java.impl, + com.ibm.wala.ecore.java.pointerAnalysis, + com.ibm.wala.ecore.java.pointerAnalysis.impl, + com.ibm.wala.ecore.java.pointerAnalysis.util, + com.ibm.wala.ecore.java.scope, + com.ibm.wala.ecore.java.scope.impl, + com.ibm.wala.ecore.java.scope.util, + com.ibm.wala.ecore.java.util, + com.ibm.wala.ecore.perf, + com.ibm.wala.ecore.perf.impl, + com.ibm.wala.ecore.perf.util, + com.ibm.wala.ecore.regex, + com.ibm.wala.ecore.regex.impl, + com.ibm.wala.ecore.regex.util diff --git a/com.ibm.wala.emf/com.ibm.wala.emf/build.properties b/com.ibm.wala.emf/com.ibm.wala.emf/build.properties new file mode 100644 index 000000000..bddf3d191 --- /dev/null +++ b/com.ibm.wala.emf/com.ibm.wala.emf/build.properties @@ -0,0 +1,13 @@ +# +# +# +# $Id$ + +bin.includes = .,\ + META-INF/,\ + plugin.xml,\ + plugin.properties +jars.compile.order = . +source.. = src/,\ + models/ +output.. = bin/ diff --git a/com.ibm.wala.emf/com.ibm.wala.emf/build.xml b/com.ibm.wala.emf/com.ibm.wala.emf/build.xml new file mode 100644 index 000000000..b2a70b391 --- /dev/null +++ b/com.ibm.wala.emf/com.ibm.wala.emf/build.xml @@ -0,0 +1,187 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/com.ibm.wala.emf/com.ibm.wala.emf/models/wala.ecore b/com.ibm.wala.emf/com.ibm.wala.emf/models/wala.ecore new file mode 100644 index 000000000..e945224a6 --- /dev/null +++ b/com.ibm.wala.emf/com.ibm.wala.emf/models/wala.ecore @@ -0,0 +1,200 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/com.ibm.wala.emf/com.ibm.wala.emf/models/wala.genmodel b/com.ibm.wala.emf/com.ibm.wala.emf/models/wala.genmodel new file mode 100644 index 000000000..d833d9e98 --- /dev/null +++ b/com.ibm.wala.emf/com.ibm.wala.emf/models/wala.genmodel @@ -0,0 +1,176 @@ + + + wala.ecore + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/com.ibm.wala.emf/com.ibm.wala.emf/plugin.properties b/com.ibm.wala.emf/com.ibm.wala.emf/plugin.properties new file mode 100644 index 000000000..847749489 --- /dev/null +++ b/com.ibm.wala.emf/com.ibm.wala.emf/plugin.properties @@ -0,0 +1,20 @@ +# +# +# +# $Id$ + +# ==================================================================== +# To code developer: +# Do NOT change the properties between this line and the +# "%%% END OF TRANSLATED PROPERTIES %%%" line. +# Make a new property name, append to the end of the file and change +# the code to use the new property. +# ==================================================================== + +# ==================================================================== +# %%% END OF TRANSLATED PROPERTIES %%% +# ==================================================================== + +pluginName = Wala Model +providerName = www.example.org + diff --git a/com.ibm.wala.emf/com.ibm.wala.emf/plugin.xml b/com.ibm.wala.emf/com.ibm.wala.emf/plugin.xml new file mode 100644 index 000000000..bed6e9d91 --- /dev/null +++ b/com.ibm.wala.emf/com.ibm.wala.emf/plugin.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + diff --git a/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/common/CommonFactory.java b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/common/CommonFactory.java new file mode 100644 index 000000000..8ce4e1d67 --- /dev/null +++ b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/common/CommonFactory.java @@ -0,0 +1,91 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.common; + +import org.eclipse.emf.ecore.EFactory; + +/** + * + * The Factory for the model. + * It provides a create method for each non-abstract class of the model. + * + * @see com.ibm.wala.ecore.common.CommonPackage + * @generated + */ +public interface CommonFactory extends EFactory { + /** + * The singleton instance of the factory. + * + * + * @generated + */ + CommonFactory eINSTANCE = com.ibm.wala.ecore.common.impl.CommonFactoryImpl.init(); + + /** + * Returns a new object of class 'EPair'. + * + * + * @return a new object of class 'EPair'. + * @generated + */ + EPair createEPair(); + + /** + * Returns a new object of class 'ERelation'. + * + * + * @return a new object of class 'ERelation'. + * @generated + */ + ERelation createERelation(); + + /** + * Returns a new object of class 'EContainer'. + * + * + * @return a new object of class 'EContainer'. + * @generated + */ + EContainer createEContainer(); + + /** + * Returns a new object of class 'ENot Container'. + * + * + * @return a new object of class 'ENot Container'. + * @generated + */ + ENotContainer createENotContainer(); + + /** + * Returns a new object of class 'EString Holder'. + * + * + * @return a new object of class 'EString Holder'. + * @generated + */ + EStringHolder createEStringHolder(); + + /** + * Returns a new object of class 'EObject With Container Id'. + * + * + * @return a new object of class 'EObject With Container Id'. + * @generated + */ + EObjectWithContainerId createEObjectWithContainerId(); + + /** + * Returns the package supported by this factory. + * + * + * @return the package supported by this factory. + * @generated + */ + CommonPackage getCommonPackage(); + +} //CommonFactory diff --git a/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/common/CommonPackage.java b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/common/CommonPackage.java new file mode 100644 index 000000000..db5c524cc --- /dev/null +++ b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/common/CommonPackage.java @@ -0,0 +1,714 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.common; + +import org.eclipse.emf.ecore.EAttribute; +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EDataType; +import org.eclipse.emf.ecore.EPackage; +import org.eclipse.emf.ecore.EReference; + +/** + * + * The Package for the model. + * It contains accessors for the meta objects to represent + *

                                + *
                              • each class,
                              • + *
                              • each feature of each class,
                              • + *
                              • each enum,
                              • + *
                              • and each data type
                              • + *
                              + * + * @see com.ibm.wala.ecore.common.CommonFactory + * @model kind="package" + * @generated + */ +public interface CommonPackage extends EPackage { + /** + * The package name. + * + * + * @generated + */ + String eNAME = "common"; + + /** + * The package namespace URI. + * + * + * @generated + */ + String eNS_URI = "http:///com/ibm/wala/wala.ecore.common"; + + /** + * The package namespace name. + * + * + * @generated + */ + String eNS_PREFIX = "com.ibm.wala.common"; + + /** + * The singleton instance of the package. + * + * + * @generated + */ + CommonPackage eINSTANCE = com.ibm.wala.ecore.common.impl.CommonPackageImpl.init(); + + /** + * The meta object id for the '{@link com.ibm.wala.ecore.common.ECollection ECollection}' class. + * + * + * @see com.ibm.wala.ecore.common.ECollection + * @see com.ibm.wala.ecore.common.impl.CommonPackageImpl#getECollection() + * @generated + */ + int ECOLLECTION = 0; + + /** + * The feature id for the 'Contents' reference list. + * + * + * @generated + * @ordered + */ + int ECOLLECTION__CONTENTS = 0; + + /** + * The number of structural features of the 'ECollection' class. + * + * + * @generated + * @ordered + */ + int ECOLLECTION_FEATURE_COUNT = 1; + + /** + * The meta object id for the '{@link com.ibm.wala.ecore.common.impl.EPairImpl EPair}' class. + * + * + * @see com.ibm.wala.ecore.common.impl.EPairImpl + * @see com.ibm.wala.ecore.common.impl.CommonPackageImpl#getEPair() + * @generated + */ + int EPAIR = 1; + + /** + * The feature id for the 'X' reference. + * + * + * @generated + * @ordered + */ + int EPAIR__X = 0; + + /** + * The feature id for the 'Y' reference. + * + * + * @generated + * @ordered + */ + int EPAIR__Y = 1; + + /** + * The number of structural features of the 'EPair' class. + * + * + * @generated + * @ordered + */ + int EPAIR_FEATURE_COUNT = 2; + + /** + * The meta object id for the '{@link com.ibm.wala.ecore.common.impl.EContainerImpl EContainer}' class. + * + * + * @see com.ibm.wala.ecore.common.impl.EContainerImpl + * @see com.ibm.wala.ecore.common.impl.CommonPackageImpl#getEContainer() + * @generated + */ + int ECONTAINER = 3; + + /** + * The feature id for the 'Contents' reference list. + * + * + * @generated + * @ordered + */ + int ECONTAINER__CONTENTS = ECOLLECTION__CONTENTS; + + /** + * The feature id for the 'Containees' containment reference list. + * + * + * @generated + * @ordered + */ + int ECONTAINER__CONTAINEES = ECOLLECTION_FEATURE_COUNT + 0; + + /** + * The number of structural features of the 'EContainer' class. + * + * + * @generated + * @ordered + */ + int ECONTAINER_FEATURE_COUNT = ECOLLECTION_FEATURE_COUNT + 1; + + /** + * The meta object id for the '{@link com.ibm.wala.ecore.common.impl.ERelationImpl ERelation}' class. + * + * + * @see com.ibm.wala.ecore.common.impl.ERelationImpl + * @see com.ibm.wala.ecore.common.impl.CommonPackageImpl#getERelation() + * @generated + */ + int ERELATION = 2; + + /** + * The feature id for the 'Contents' reference list. + * + * + * @generated + * @ordered + */ + int ERELATION__CONTENTS = ECONTAINER__CONTENTS; + + /** + * The feature id for the 'Containees' containment reference list. + * + * + * @generated + * @ordered + */ + int ERELATION__CONTAINEES = ECONTAINER__CONTAINEES; + + /** + * The feature id for the 'Name' attribute. + * + * + * @generated + * @ordered + */ + int ERELATION__NAME = ECONTAINER_FEATURE_COUNT + 0; + + /** + * The number of structural features of the 'ERelation' class. + * + * + * @generated + * @ordered + */ + int ERELATION_FEATURE_COUNT = ECONTAINER_FEATURE_COUNT + 1; + + /** + * The meta object id for the '{@link com.ibm.wala.ecore.common.impl.ENotContainerImpl ENot Container}' class. + * + * + * @see com.ibm.wala.ecore.common.impl.ENotContainerImpl + * @see com.ibm.wala.ecore.common.impl.CommonPackageImpl#getENotContainer() + * @generated + */ + int ENOT_CONTAINER = 4; + + /** + * The feature id for the 'Contents' reference list. + * + * + * @generated + * @ordered + */ + int ENOT_CONTAINER__CONTENTS = ECOLLECTION__CONTENTS; + + /** + * The feature id for the 'Elements' reference list. + * + * + * @generated + * @ordered + */ + int ENOT_CONTAINER__ELEMENTS = ECOLLECTION_FEATURE_COUNT + 0; + + /** + * The number of structural features of the 'ENot Container' class. + * + * + * @generated + * @ordered + */ + int ENOT_CONTAINER_FEATURE_COUNT = ECOLLECTION_FEATURE_COUNT + 1; + + /** + * The meta object id for the '{@link com.ibm.wala.ecore.common.impl.EStringHolderImpl EString Holder}' class. + * + * + * @see com.ibm.wala.ecore.common.impl.EStringHolderImpl + * @see com.ibm.wala.ecore.common.impl.CommonPackageImpl#getEStringHolder() + * @generated + */ + int ESTRING_HOLDER = 5; + + /** + * The feature id for the 'Value' attribute. + * + * + * @generated + * @ordered + */ + int ESTRING_HOLDER__VALUE = 0; + + /** + * The number of structural features of the 'EString Holder' class. + * + * + * @generated + * @ordered + */ + int ESTRING_HOLDER_FEATURE_COUNT = 1; + + /** + * The meta object id for the '{@link com.ibm.wala.ecore.common.impl.EObjectWithContainerIdImpl EObject With Container Id}' class. + * + * + * @see com.ibm.wala.ecore.common.impl.EObjectWithContainerIdImpl + * @see com.ibm.wala.ecore.common.impl.CommonPackageImpl#getEObjectWithContainerId() + * @generated + */ + int EOBJECT_WITH_CONTAINER_ID = 6; + + /** + * The feature id for the 'Id' attribute. + * + * + * @generated + * @ordered + */ + int EOBJECT_WITH_CONTAINER_ID__ID = 0; + + /** + * The number of structural features of the 'EObject With Container Id' class. + * + * + * @generated + * @ordered + */ + int EOBJECT_WITH_CONTAINER_ID_FEATURE_COUNT = 1; + + /** + * The meta object id for the 'EJava Collection' data type. + * + * + * @see java.util.Collection + * @see com.ibm.wala.ecore.common.impl.CommonPackageImpl#getEJavaCollection() + * @generated + */ + int EJAVA_COLLECTION = 7; + + /** + * The meta object id for the 'EFile' data type. + * + * + * @see java.io.File + * @see com.ibm.wala.ecore.common.impl.CommonPackageImpl#getEFile() + * @generated + */ + int EFILE = 8; + + /** + * The meta object id for the 'EIterator' data type. + * + * + * @see java.util.Iterator + * @see com.ibm.wala.ecore.common.impl.CommonPackageImpl#getEIterator() + * @generated + */ + int EITERATOR = 9; + + + /** + * Returns the meta object for class '{@link com.ibm.wala.ecore.common.ECollection ECollection}'. + * + * + * @return the meta object for class 'ECollection'. + * @see com.ibm.wala.ecore.common.ECollection + * @generated + */ + EClass getECollection(); + + /** + * Returns the meta object for the reference list '{@link com.ibm.wala.ecore.common.ECollection#getContents Contents}'. + * + * + * @return the meta object for the reference list 'Contents'. + * @see com.ibm.wala.ecore.common.ECollection#getContents() + * @see #getECollection() + * @generated + */ + EReference getECollection_Contents(); + + /** + * Returns the meta object for class '{@link com.ibm.wala.ecore.common.EPair EPair}'. + * + * + * @return the meta object for class 'EPair'. + * @see com.ibm.wala.ecore.common.EPair + * @generated + */ + EClass getEPair(); + + /** + * Returns the meta object for the reference '{@link com.ibm.wala.ecore.common.EPair#getX X}'. + * + * + * @return the meta object for the reference 'X'. + * @see com.ibm.wala.ecore.common.EPair#getX() + * @see #getEPair() + * @generated + */ + EReference getEPair_X(); + + /** + * Returns the meta object for the reference '{@link com.ibm.wala.ecore.common.EPair#getY Y}'. + * + * + * @return the meta object for the reference 'Y'. + * @see com.ibm.wala.ecore.common.EPair#getY() + * @see #getEPair() + * @generated + */ + EReference getEPair_Y(); + + /** + * Returns the meta object for class '{@link com.ibm.wala.ecore.common.ERelation ERelation}'. + * + * + * @return the meta object for class 'ERelation'. + * @see com.ibm.wala.ecore.common.ERelation + * @generated + */ + EClass getERelation(); + + /** + * Returns the meta object for the attribute '{@link com.ibm.wala.ecore.common.ERelation#getName Name}'. + * + * + * @return the meta object for the attribute 'Name'. + * @see com.ibm.wala.ecore.common.ERelation#getName() + * @see #getERelation() + * @generated + */ + EAttribute getERelation_Name(); + + /** + * Returns the meta object for class '{@link com.ibm.wala.ecore.common.EContainer EContainer}'. + * + * + * @return the meta object for class 'EContainer'. + * @see com.ibm.wala.ecore.common.EContainer + * @generated + */ + EClass getEContainer(); + + /** + * Returns the meta object for the containment reference list '{@link com.ibm.wala.ecore.common.EContainer#getContainees Containees}'. + * + * + * @return the meta object for the containment reference list 'Containees'. + * @see com.ibm.wala.ecore.common.EContainer#getContainees() + * @see #getEContainer() + * @generated + */ + EReference getEContainer_Containees(); + + /** + * Returns the meta object for class '{@link com.ibm.wala.ecore.common.ENotContainer ENot Container}'. + * + * + * @return the meta object for class 'ENot Container'. + * @see com.ibm.wala.ecore.common.ENotContainer + * @generated + */ + EClass getENotContainer(); + + /** + * Returns the meta object for the reference list '{@link com.ibm.wala.ecore.common.ENotContainer#getElements Elements}'. + * + * + * @return the meta object for the reference list 'Elements'. + * @see com.ibm.wala.ecore.common.ENotContainer#getElements() + * @see #getENotContainer() + * @generated + */ + EReference getENotContainer_Elements(); + + /** + * Returns the meta object for class '{@link com.ibm.wala.ecore.common.EStringHolder EString Holder}'. + * + * + * @return the meta object for class 'EString Holder'. + * @see com.ibm.wala.ecore.common.EStringHolder + * @generated + */ + EClass getEStringHolder(); + + /** + * Returns the meta object for the attribute '{@link com.ibm.wala.ecore.common.EStringHolder#getValue Value}'. + * + * + * @return the meta object for the attribute 'Value'. + * @see com.ibm.wala.ecore.common.EStringHolder#getValue() + * @see #getEStringHolder() + * @generated + */ + EAttribute getEStringHolder_Value(); + + /** + * Returns the meta object for class '{@link com.ibm.wala.ecore.common.EObjectWithContainerId EObject With Container Id}'. + * + * + * @return the meta object for class 'EObject With Container Id'. + * @see com.ibm.wala.ecore.common.EObjectWithContainerId + * @generated + */ + EClass getEObjectWithContainerId(); + + /** + * Returns the meta object for the attribute '{@link com.ibm.wala.ecore.common.EObjectWithContainerId#getId Id}'. + * + * + * @return the meta object for the attribute 'Id'. + * @see com.ibm.wala.ecore.common.EObjectWithContainerId#getId() + * @see #getEObjectWithContainerId() + * @generated + */ + EAttribute getEObjectWithContainerId_Id(); + + /** + * Returns the meta object for data type '{@link java.util.Collection EJava Collection}'. + * + * + * @return the meta object for data type 'EJava Collection'. + * @see java.util.Collection + * @model instanceClass="java.util.Collection" serializable="false" + * @generated + */ + EDataType getEJavaCollection(); + + /** + * Returns the meta object for data type '{@link java.io.File EFile}'. + * + * + * @return the meta object for data type 'EFile'. + * @see java.io.File + * @model instanceClass="java.io.File" serializable="false" + * @generated + */ + EDataType getEFile(); + + /** + * Returns the meta object for data type '{@link java.util.Iterator EIterator}'. + * + * + * @return the meta object for data type 'EIterator'. + * @see java.util.Iterator + * @model instanceClass="java.util.Iterator" serializable="false" + * @generated + */ + EDataType getEIterator(); + + /** + * Returns the factory that creates the instances of the model. + * + * + * @return the factory that creates the instances of the model. + * @generated + */ + CommonFactory getCommonFactory(); + + /** + * + * Defines literals for the meta objects that represent + *
                                + *
                              • each class,
                              • + *
                              • each feature of each class,
                              • + *
                              • each enum,
                              • + *
                              • and each data type
                              • + *
                              + * + * @generated + */ + interface Literals { + /** + * The meta object literal for the '{@link com.ibm.wala.ecore.common.ECollection ECollection}' class. + * + * + * @see com.ibm.wala.ecore.common.ECollection + * @see com.ibm.wala.ecore.common.impl.CommonPackageImpl#getECollection() + * @generated + */ + EClass ECOLLECTION = eINSTANCE.getECollection(); + + /** + * The meta object literal for the 'Contents' reference list feature. + * + * + * @generated + */ + EReference ECOLLECTION__CONTENTS = eINSTANCE.getECollection_Contents(); + + /** + * The meta object literal for the '{@link com.ibm.wala.ecore.common.impl.EPairImpl EPair}' class. + * + * + * @see com.ibm.wala.ecore.common.impl.EPairImpl + * @see com.ibm.wala.ecore.common.impl.CommonPackageImpl#getEPair() + * @generated + */ + EClass EPAIR = eINSTANCE.getEPair(); + + /** + * The meta object literal for the 'X' reference feature. + * + * + * @generated + */ + EReference EPAIR__X = eINSTANCE.getEPair_X(); + + /** + * The meta object literal for the 'Y' reference feature. + * + * + * @generated + */ + EReference EPAIR__Y = eINSTANCE.getEPair_Y(); + + /** + * The meta object literal for the '{@link com.ibm.wala.ecore.common.impl.ERelationImpl ERelation}' class. + * + * + * @see com.ibm.wala.ecore.common.impl.ERelationImpl + * @see com.ibm.wala.ecore.common.impl.CommonPackageImpl#getERelation() + * @generated + */ + EClass ERELATION = eINSTANCE.getERelation(); + + /** + * The meta object literal for the 'Name' attribute feature. + * + * + * @generated + */ + EAttribute ERELATION__NAME = eINSTANCE.getERelation_Name(); + + /** + * The meta object literal for the '{@link com.ibm.wala.ecore.common.impl.EContainerImpl EContainer}' class. + * + * + * @see com.ibm.wala.ecore.common.impl.EContainerImpl + * @see com.ibm.wala.ecore.common.impl.CommonPackageImpl#getEContainer() + * @generated + */ + EClass ECONTAINER = eINSTANCE.getEContainer(); + + /** + * The meta object literal for the 'Containees' containment reference list feature. + * + * + * @generated + */ + EReference ECONTAINER__CONTAINEES = eINSTANCE.getEContainer_Containees(); + + /** + * The meta object literal for the '{@link com.ibm.wala.ecore.common.impl.ENotContainerImpl ENot Container}' class. + * + * + * @see com.ibm.wala.ecore.common.impl.ENotContainerImpl + * @see com.ibm.wala.ecore.common.impl.CommonPackageImpl#getENotContainer() + * @generated + */ + EClass ENOT_CONTAINER = eINSTANCE.getENotContainer(); + + /** + * The meta object literal for the 'Elements' reference list feature. + * + * + * @generated + */ + EReference ENOT_CONTAINER__ELEMENTS = eINSTANCE.getENotContainer_Elements(); + + /** + * The meta object literal for the '{@link com.ibm.wala.ecore.common.impl.EStringHolderImpl EString Holder}' class. + * + * + * @see com.ibm.wala.ecore.common.impl.EStringHolderImpl + * @see com.ibm.wala.ecore.common.impl.CommonPackageImpl#getEStringHolder() + * @generated + */ + EClass ESTRING_HOLDER = eINSTANCE.getEStringHolder(); + + /** + * The meta object literal for the 'Value' attribute feature. + * + * + * @generated + */ + EAttribute ESTRING_HOLDER__VALUE = eINSTANCE.getEStringHolder_Value(); + + /** + * The meta object literal for the '{@link com.ibm.wala.ecore.common.impl.EObjectWithContainerIdImpl EObject With Container Id}' class. + * + * + * @see com.ibm.wala.ecore.common.impl.EObjectWithContainerIdImpl + * @see com.ibm.wala.ecore.common.impl.CommonPackageImpl#getEObjectWithContainerId() + * @generated + */ + EClass EOBJECT_WITH_CONTAINER_ID = eINSTANCE.getEObjectWithContainerId(); + + /** + * The meta object literal for the 'Id' attribute feature. + * + * + * @generated + */ + EAttribute EOBJECT_WITH_CONTAINER_ID__ID = eINSTANCE.getEObjectWithContainerId_Id(); + + /** + * The meta object literal for the 'EJava Collection' data type. + * + * + * @see java.util.Collection + * @see com.ibm.wala.ecore.common.impl.CommonPackageImpl#getEJavaCollection() + * @generated + */ + EDataType EJAVA_COLLECTION = eINSTANCE.getEJavaCollection(); + + /** + * The meta object literal for the 'EFile' data type. + * + * + * @see java.io.File + * @see com.ibm.wala.ecore.common.impl.CommonPackageImpl#getEFile() + * @generated + */ + EDataType EFILE = eINSTANCE.getEFile(); + + /** + * The meta object literal for the 'EIterator' data type. + * + * + * @see java.util.Iterator + * @see com.ibm.wala.ecore.common.impl.CommonPackageImpl#getEIterator() + * @generated + */ + EDataType EITERATOR = eINSTANCE.getEIterator(); + + } + +} //CommonPackage diff --git a/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/common/ECollection.java b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/common/ECollection.java new file mode 100644 index 000000000..fd6493a00 --- /dev/null +++ b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/common/ECollection.java @@ -0,0 +1,46 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.common; + +import org.eclipse.emf.common.util.EList; + +import org.eclipse.emf.ecore.EObject; + +/** + * + * A representation of the model object 'ECollection'. + * + * + *

                              + * The following features are supported: + *

                                + *
                              • {@link com.ibm.wala.ecore.common.ECollection#getContents Contents}
                              • + *
                              + *

                              + * + * @see com.ibm.wala.ecore.common.CommonPackage#getECollection() + * @model interface="true" abstract="true" + * @generated + */ +public interface ECollection extends EObject { + /** + * Returns the value of the 'Contents' reference list. + * The list contents are of type {@link org.eclipse.emf.ecore.EObject}. + * + *

                              + * If the meaning of the 'Contents' reference list isn't clear, + * there really should be more of a description here... + *

                              + * + * @return the value of the 'Contents' reference list. + * @see com.ibm.wala.ecore.common.CommonPackage#getECollection_Contents() + * @model type="org.eclipse.emf.ecore.EObject" transient="true" volatile="true" + * @generated + */ + EList getContents(); + +} // ECollection \ No newline at end of file diff --git a/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/common/EContainer.java b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/common/EContainer.java new file mode 100644 index 000000000..66e3a7b75 --- /dev/null +++ b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/common/EContainer.java @@ -0,0 +1,44 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.common; + +import org.eclipse.emf.common.util.EList; + +/** + * + * A representation of the model object 'EContainer'. + * + * + *

                              + * The following features are supported: + *

                                + *
                              • {@link com.ibm.wala.ecore.common.EContainer#getContainees Containees}
                              • + *
                              + *

                              + * + * @see com.ibm.wala.ecore.common.CommonPackage#getEContainer() + * @model + * @generated + */ +public interface EContainer extends ECollection { + /** + * Returns the value of the 'Containees' containment reference list. + * The list contents are of type {@link org.eclipse.emf.ecore.EObject}. + * + *

                              + * If the meaning of the 'Containees' containment reference list isn't clear, + * there really should be more of a description here... + *

                              + * + * @return the value of the 'Containees' containment reference list. + * @see com.ibm.wala.ecore.common.CommonPackage#getEContainer_Containees() + * @model type="org.eclipse.emf.ecore.EObject" containment="true" + * @generated + */ + EList getContainees(); + +} // EContainer \ No newline at end of file diff --git a/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/common/ENotContainer.java b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/common/ENotContainer.java new file mode 100644 index 000000000..ca4382c1f --- /dev/null +++ b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/common/ENotContainer.java @@ -0,0 +1,44 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.common; + +import org.eclipse.emf.common.util.EList; + +/** + * + * A representation of the model object 'ENot Container'. + * + * + *

                              + * The following features are supported: + *

                                + *
                              • {@link com.ibm.wala.ecore.common.ENotContainer#getElements Elements}
                              • + *
                              + *

                              + * + * @see com.ibm.wala.ecore.common.CommonPackage#getENotContainer() + * @model + * @generated + */ +public interface ENotContainer extends ECollection { + /** + * Returns the value of the 'Elements' reference list. + * The list contents are of type {@link org.eclipse.emf.ecore.EObject}. + * + *

                              + * If the meaning of the 'Elements' reference list isn't clear, + * there really should be more of a description here... + *

                              + * + * @return the value of the 'Elements' reference list. + * @see com.ibm.wala.ecore.common.CommonPackage#getENotContainer_Elements() + * @model type="org.eclipse.emf.ecore.EObject" + * @generated + */ + EList getElements(); + +} // ENotContainer \ No newline at end of file diff --git a/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/common/EObjectWithContainerId.java b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/common/EObjectWithContainerId.java new file mode 100644 index 000000000..f8c2d2d43 --- /dev/null +++ b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/common/EObjectWithContainerId.java @@ -0,0 +1,55 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.common; + +import org.eclipse.emf.ecore.EObject; + +/** + * + * A representation of the model object 'EObject With Container Id'. + * + * + *

                              + * The following features are supported: + *

                                + *
                              • {@link com.ibm.wala.ecore.common.EObjectWithContainerId#getId Id}
                              • + *
                              + *

                              + * + * @see com.ibm.wala.ecore.common.CommonPackage#getEObjectWithContainerId() + * @model + * @generated + */ +public interface EObjectWithContainerId extends EObject { + /** + * Returns the value of the 'Id' attribute. + * The default value is "-1". + * + *

                              + * If the meaning of the 'Id' attribute isn't clear, + * there really should be more of a description here... + *

                              + * + * @return the value of the 'Id' attribute. + * @see #setId(int) + * @see com.ibm.wala.ecore.common.CommonPackage#getEObjectWithContainerId_Id() + * @model default="-1" id="true" required="true" + * @generated + */ + int getId(); + + /** + * Sets the value of the '{@link com.ibm.wala.ecore.common.EObjectWithContainerId#getId Id}' attribute. + * + * + * @param value the new value of the 'Id' attribute. + * @see #getId() + * @generated + */ + void setId(int value); + +} // EObjectWithContainerId \ No newline at end of file diff --git a/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/common/EPair.java b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/common/EPair.java new file mode 100644 index 000000000..ee9b22528 --- /dev/null +++ b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/common/EPair.java @@ -0,0 +1,81 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.common; + +import org.eclipse.emf.ecore.EObject; + +/** + * + * A representation of the model object 'EPair'. + * + * + *

                              + * The following features are supported: + *

                                + *
                              • {@link com.ibm.wala.ecore.common.EPair#getX X}
                              • + *
                              • {@link com.ibm.wala.ecore.common.EPair#getY Y}
                              • + *
                              + *

                              + * + * @see com.ibm.wala.ecore.common.CommonPackage#getEPair() + * @model + * @generated + */ +public interface EPair extends EObject { + /** + * Returns the value of the 'X' reference. + * + *

                              + * If the meaning of the 'X' reference isn't clear, + * there really should be more of a description here... + *

                              + * + * @return the value of the 'X' reference. + * @see #setX(EObject) + * @see com.ibm.wala.ecore.common.CommonPackage#getEPair_X() + * @model required="true" + * @generated + */ + EObject getX(); + + /** + * Sets the value of the '{@link com.ibm.wala.ecore.common.EPair#getX X}' reference. + * + * + * @param value the new value of the 'X' reference. + * @see #getX() + * @generated + */ + void setX(EObject value); + + /** + * Returns the value of the 'Y' reference. + * + *

                              + * If the meaning of the 'Y' reference isn't clear, + * there really should be more of a description here... + *

                              + * + * @return the value of the 'Y' reference. + * @see #setY(EObject) + * @see com.ibm.wala.ecore.common.CommonPackage#getEPair_Y() + * @model required="true" + * @generated + */ + EObject getY(); + + /** + * Sets the value of the '{@link com.ibm.wala.ecore.common.EPair#getY Y}' reference. + * + * + * @param value the new value of the 'Y' reference. + * @see #getY() + * @generated + */ + void setY(EObject value); + +} // EPair \ No newline at end of file diff --git a/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/common/ERelation.java b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/common/ERelation.java new file mode 100644 index 000000000..9f52a6004 --- /dev/null +++ b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/common/ERelation.java @@ -0,0 +1,53 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.common; + + +/** + * + * A representation of the model object 'ERelation'. + * + * + *

                              + * The following features are supported: + *

                                + *
                              • {@link com.ibm.wala.ecore.common.ERelation#getName Name}
                              • + *
                              + *

                              + * + * @see com.ibm.wala.ecore.common.CommonPackage#getERelation() + * @model + * @generated + */ +public interface ERelation extends EContainer { + /** + * Returns the value of the 'Name' attribute. + * + *

                              + * If the meaning of the 'Name' attribute isn't clear, + * there really should be more of a description here... + *

                              + * + * @return the value of the 'Name' attribute. + * @see #setName(String) + * @see com.ibm.wala.ecore.common.CommonPackage#getERelation_Name() + * @model + * @generated + */ + String getName(); + + /** + * Sets the value of the '{@link com.ibm.wala.ecore.common.ERelation#getName Name}' attribute. + * + * + * @param value the new value of the 'Name' attribute. + * @see #getName() + * @generated + */ + void setName(String value); + +} // ERelation \ No newline at end of file diff --git a/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/common/EStringHolder.java b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/common/EStringHolder.java new file mode 100644 index 000000000..606b59a9e --- /dev/null +++ b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/common/EStringHolder.java @@ -0,0 +1,54 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.common; + +import org.eclipse.emf.ecore.EObject; + +/** + * + * A representation of the model object 'EString Holder'. + * + * + *

                              + * The following features are supported: + *

                                + *
                              • {@link com.ibm.wala.ecore.common.EStringHolder#getValue Value}
                              • + *
                              + *

                              + * + * @see com.ibm.wala.ecore.common.CommonPackage#getEStringHolder() + * @model + * @generated + */ +public interface EStringHolder extends EObject { + /** + * Returns the value of the 'Value' attribute. + * + *

                              + * If the meaning of the 'Value' attribute isn't clear, + * there really should be more of a description here... + *

                              + * + * @return the value of the 'Value' attribute. + * @see #setValue(String) + * @see com.ibm.wala.ecore.common.CommonPackage#getEStringHolder_Value() + * @model required="true" + * @generated + */ + String getValue(); + + /** + * Sets the value of the '{@link com.ibm.wala.ecore.common.EStringHolder#getValue Value}' attribute. + * + * + * @param value the new value of the 'Value' attribute. + * @see #getValue() + * @generated + */ + void setValue(String value); + +} // EStringHolder \ No newline at end of file diff --git a/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/common/impl/CommonFactoryImpl.java b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/common/impl/CommonFactoryImpl.java new file mode 100644 index 000000000..2eac2e2e4 --- /dev/null +++ b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/common/impl/CommonFactoryImpl.java @@ -0,0 +1,177 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.common.impl; + +import com.ibm.wala.ecore.common.*; + +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EDataType; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EPackage; + +import org.eclipse.emf.ecore.impl.EFactoryImpl; + +import org.eclipse.emf.ecore.plugin.EcorePlugin; + +/** + * + * An implementation of the model Factory. + * + * @generated + */ +public class CommonFactoryImpl extends EFactoryImpl implements CommonFactory { + /** + * Creates the default factory implementation. + * + * + * @generated + */ + public static CommonFactory init() { + try { + CommonFactory theCommonFactory = (CommonFactory)EPackage.Registry.INSTANCE.getEFactory("http:///com/ibm/wala/wala.ecore.common"); + if (theCommonFactory != null) { + return theCommonFactory; + } + } + catch (Exception exception) { + EcorePlugin.INSTANCE.log(exception); + } + return new CommonFactoryImpl(); + } + + /** + * Creates an instance of the factory. + * + * + * @generated + */ + public CommonFactoryImpl() { + super(); + } + + /** + * + * + * @generated + */ + public EObject create(EClass eClass) { + switch (eClass.getClassifierID()) { + case CommonPackage.EPAIR: return createEPair(); + case CommonPackage.ERELATION: return createERelation(); + case CommonPackage.ECONTAINER: return createEContainer(); + case CommonPackage.ENOT_CONTAINER: return createENotContainer(); + case CommonPackage.ESTRING_HOLDER: return createEStringHolder(); + case CommonPackage.EOBJECT_WITH_CONTAINER_ID: return createEObjectWithContainerId(); + default: + throw new IllegalArgumentException("The class '" + eClass.getName() + "' is not a valid classifier"); + } + } + + /** + * + * + * @generated + */ + public Object createFromString(EDataType eDataType, String initialValue) { + switch (eDataType.getClassifierID()) { + default: + throw new IllegalArgumentException("The datatype '" + eDataType.getName() + "' is not a valid classifier"); + } + } + + /** + * + * + * @generated + */ + public String convertToString(EDataType eDataType, Object instanceValue) { + switch (eDataType.getClassifierID()) { + default: + throw new IllegalArgumentException("The datatype '" + eDataType.getName() + "' is not a valid classifier"); + } + } + + /** + * + * + * @generated + */ + public EPair createEPair() { + EPairImpl ePair = new EPairImpl(); + return ePair; + } + + /** + * + * + * @generated + */ + public ERelation createERelation() { + ERelationImpl eRelation = new ERelationImpl(); + return eRelation; + } + + /** + * + * + * @generated + */ + public EContainer createEContainer() { + EContainerImpl eContainer = new EContainerImpl(); + return eContainer; + } + + /** + * + * + * @generated + */ + public ENotContainer createENotContainer() { + ENotContainerImpl eNotContainer = new ENotContainerImpl(); + return eNotContainer; + } + + /** + * + * + * @generated + */ + public EStringHolder createEStringHolder() { + EStringHolderImpl eStringHolder = new EStringHolderImpl(); + return eStringHolder; + } + + /** + * + * + * @generated + */ + public EObjectWithContainerId createEObjectWithContainerId() { + EObjectWithContainerIdImpl eObjectWithContainerId = new EObjectWithContainerIdImpl(); + return eObjectWithContainerId; + } + + /** + * + * + * @generated + */ + public CommonPackage getCommonPackage() { + return (CommonPackage)getEPackage(); + } + + /** + * + * + * @deprecated + * @generated + */ + public static CommonPackage getPackage() { + return CommonPackage.eINSTANCE; + } + +} //CommonFactoryImpl diff --git a/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/common/impl/CommonPackageImpl.java b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/common/impl/CommonPackageImpl.java new file mode 100644 index 000000000..7089e7778 --- /dev/null +++ b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/common/impl/CommonPackageImpl.java @@ -0,0 +1,513 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.common.impl; + +import com.ibm.wala.ecore.common.CommonFactory; +import com.ibm.wala.ecore.common.CommonPackage; +import com.ibm.wala.ecore.common.ECollection; +import com.ibm.wala.ecore.common.EContainer; +import com.ibm.wala.ecore.common.ENotContainer; +import com.ibm.wala.ecore.common.EObjectWithContainerId; +import com.ibm.wala.ecore.common.EPair; +import com.ibm.wala.ecore.common.ERelation; +import com.ibm.wala.ecore.common.EStringHolder; + +import com.ibm.wala.ecore.graph.GraphPackage; + +import com.ibm.wala.ecore.graph.impl.GraphPackageImpl; + +import com.ibm.wala.ecore.j2ee.scope.J2EEScopePackage; + +import com.ibm.wala.ecore.j2ee.scope.impl.J2EEScopePackageImpl; + +import com.ibm.wala.ecore.java.JavaPackage; + +import com.ibm.wala.ecore.java.callGraph.CallGraphPackage; + +import com.ibm.wala.ecore.java.callGraph.impl.CallGraphPackageImpl; + +import com.ibm.wala.ecore.java.impl.JavaPackageImpl; + +import com.ibm.wala.ecore.java.pointerAnalysis.PointerAnalysisPackage; + +import com.ibm.wala.ecore.java.pointerAnalysis.impl.PointerAnalysisPackageImpl; + +import com.ibm.wala.ecore.java.scope.JavaScopePackage; + +import com.ibm.wala.ecore.java.scope.impl.JavaScopePackageImpl; + +import com.ibm.wala.ecore.perf.PerfPackage; + +import com.ibm.wala.ecore.perf.impl.PerfPackageImpl; + +import com.ibm.wala.ecore.regex.RegexPackage; + +import com.ibm.wala.ecore.regex.impl.RegexPackageImpl; + +import java.io.File; + +import java.util.Collection; +import java.util.Iterator; + +import org.eclipse.emf.ecore.EAttribute; +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EDataType; +import org.eclipse.emf.ecore.EPackage; +import org.eclipse.emf.ecore.EReference; + +import org.eclipse.emf.ecore.impl.EPackageImpl; + +/** + * + * An implementation of the model Package. + * + * @generated + */ +public class CommonPackageImpl extends EPackageImpl implements CommonPackage { + /** + * + * + * @generated + */ + private EClass eCollectionEClass = null; + + /** + * + * + * @generated + */ + private EClass ePairEClass = null; + + /** + * + * + * @generated + */ + private EClass eRelationEClass = null; + + /** + * + * + * @generated + */ + private EClass eContainerEClass = null; + + /** + * + * + * @generated + */ + private EClass eNotContainerEClass = null; + + /** + * + * + * @generated + */ + private EClass eStringHolderEClass = null; + + /** + * + * + * @generated + */ + private EClass eObjectWithContainerIdEClass = null; + + /** + * + * + * @generated + */ + private EDataType eJavaCollectionEDataType = null; + + /** + * + * + * @generated + */ + private EDataType eFileEDataType = null; + + /** + * + * + * @generated + */ + private EDataType eIteratorEDataType = null; + + /** + * Creates an instance of the model Package, registered with + * {@link org.eclipse.emf.ecore.EPackage.Registry EPackage.Registry} by the package + * package URI value. + *

                              Note: the correct way to create the package is via the static + * factory method {@link #init init()}, which also performs + * initialization of the package, or returns the registered package, + * if one already exists. + * + * + * @see org.eclipse.emf.ecore.EPackage.Registry + * @see com.ibm.wala.ecore.common.CommonPackage#eNS_URI + * @see #init() + * @generated + */ + private CommonPackageImpl() { + super(eNS_URI, CommonFactory.eINSTANCE); + } + + /** + * + * + * @generated + */ + private static boolean isInited = false; + + /** + * Creates, registers, and initializes the Package for this + * model, and for any others upon which it depends. Simple + * dependencies are satisfied by calling this method on all + * dependent packages before doing anything else. This method drives + * initialization for interdependent packages directly, in parallel + * with this package, itself. + *

                              Of this package and its interdependencies, all packages which + * have not yet been registered by their URI values are first created + * and registered. The packages are then initialized in two steps: + * meta-model objects for all of the packages are created before any + * are initialized, since one package's meta-model objects may refer to + * those of another. + *

                              Invocation of this method will not affect any packages that have + * already been initialized. + * + * + * @see #eNS_URI + * @see #createPackageContents() + * @see #initializePackageContents() + * @generated + */ + public static CommonPackage init() { + if (isInited) return (CommonPackage)EPackage.Registry.INSTANCE.getEPackage(CommonPackage.eNS_URI); + + // Obtain or create and register package + CommonPackageImpl theCommonPackage = (CommonPackageImpl)(EPackage.Registry.INSTANCE.getEPackage(eNS_URI) instanceof CommonPackageImpl ? EPackage.Registry.INSTANCE.getEPackage(eNS_URI) : new CommonPackageImpl()); + + isInited = true; + + // Obtain or create and register interdependencies + GraphPackageImpl theGraphPackage = (GraphPackageImpl)(EPackage.Registry.INSTANCE.getEPackage(GraphPackage.eNS_URI) instanceof GraphPackageImpl ? EPackage.Registry.INSTANCE.getEPackage(GraphPackage.eNS_URI) : GraphPackage.eINSTANCE); + RegexPackageImpl theRegexPackage = (RegexPackageImpl)(EPackage.Registry.INSTANCE.getEPackage(RegexPackage.eNS_URI) instanceof RegexPackageImpl ? EPackage.Registry.INSTANCE.getEPackage(RegexPackage.eNS_URI) : RegexPackage.eINSTANCE); + PerfPackageImpl thePerfPackage = (PerfPackageImpl)(EPackage.Registry.INSTANCE.getEPackage(PerfPackage.eNS_URI) instanceof PerfPackageImpl ? EPackage.Registry.INSTANCE.getEPackage(PerfPackage.eNS_URI) : PerfPackage.eINSTANCE); + JavaPackageImpl theJavaPackage = (JavaPackageImpl)(EPackage.Registry.INSTANCE.getEPackage(JavaPackage.eNS_URI) instanceof JavaPackageImpl ? EPackage.Registry.INSTANCE.getEPackage(JavaPackage.eNS_URI) : JavaPackage.eINSTANCE); + CallGraphPackageImpl theCallGraphPackage = (CallGraphPackageImpl)(EPackage.Registry.INSTANCE.getEPackage(CallGraphPackage.eNS_URI) instanceof CallGraphPackageImpl ? EPackage.Registry.INSTANCE.getEPackage(CallGraphPackage.eNS_URI) : CallGraphPackage.eINSTANCE); + PointerAnalysisPackageImpl thePointerAnalysisPackage = (PointerAnalysisPackageImpl)(EPackage.Registry.INSTANCE.getEPackage(PointerAnalysisPackage.eNS_URI) instanceof PointerAnalysisPackageImpl ? EPackage.Registry.INSTANCE.getEPackage(PointerAnalysisPackage.eNS_URI) : PointerAnalysisPackage.eINSTANCE); + JavaScopePackageImpl theJavaScopePackage = (JavaScopePackageImpl)(EPackage.Registry.INSTANCE.getEPackage(JavaScopePackage.eNS_URI) instanceof JavaScopePackageImpl ? EPackage.Registry.INSTANCE.getEPackage(JavaScopePackage.eNS_URI) : JavaScopePackage.eINSTANCE); + J2EEScopePackageImpl theJ2EEScopePackage = (J2EEScopePackageImpl)(EPackage.Registry.INSTANCE.getEPackage(J2EEScopePackage.eNS_URI) instanceof J2EEScopePackageImpl ? EPackage.Registry.INSTANCE.getEPackage(J2EEScopePackage.eNS_URI) : J2EEScopePackage.eINSTANCE); + + // Create package meta-data objects + theCommonPackage.createPackageContents(); + theGraphPackage.createPackageContents(); + theRegexPackage.createPackageContents(); + thePerfPackage.createPackageContents(); + theJavaPackage.createPackageContents(); + theCallGraphPackage.createPackageContents(); + thePointerAnalysisPackage.createPackageContents(); + theJavaScopePackage.createPackageContents(); + theJ2EEScopePackage.createPackageContents(); + + // Initialize created meta-data + theCommonPackage.initializePackageContents(); + theGraphPackage.initializePackageContents(); + theRegexPackage.initializePackageContents(); + thePerfPackage.initializePackageContents(); + theJavaPackage.initializePackageContents(); + theCallGraphPackage.initializePackageContents(); + thePointerAnalysisPackage.initializePackageContents(); + theJavaScopePackage.initializePackageContents(); + theJ2EEScopePackage.initializePackageContents(); + + // Mark meta-data to indicate it can't be changed + theCommonPackage.freeze(); + + return theCommonPackage; + } + + /** + * + * + * @generated + */ + public EClass getECollection() { + return eCollectionEClass; + } + + /** + * + * + * @generated + */ + public EReference getECollection_Contents() { + return (EReference)eCollectionEClass.getEStructuralFeatures().get(0); + } + + /** + * + * + * @generated + */ + public EClass getEPair() { + return ePairEClass; + } + + /** + * + * + * @generated + */ + public EReference getEPair_X() { + return (EReference)ePairEClass.getEStructuralFeatures().get(0); + } + + /** + * + * + * @generated + */ + public EReference getEPair_Y() { + return (EReference)ePairEClass.getEStructuralFeatures().get(1); + } + + /** + * + * + * @generated + */ + public EClass getERelation() { + return eRelationEClass; + } + + /** + * + * + * @generated + */ + public EAttribute getERelation_Name() { + return (EAttribute)eRelationEClass.getEStructuralFeatures().get(0); + } + + /** + * + * + * @generated + */ + public EClass getEContainer() { + return eContainerEClass; + } + + /** + * + * + * @generated + */ + public EReference getEContainer_Containees() { + return (EReference)eContainerEClass.getEStructuralFeatures().get(0); + } + + /** + * + * + * @generated + */ + public EClass getENotContainer() { + return eNotContainerEClass; + } + + /** + * + * + * @generated + */ + public EReference getENotContainer_Elements() { + return (EReference)eNotContainerEClass.getEStructuralFeatures().get(0); + } + + /** + * + * + * @generated + */ + public EClass getEStringHolder() { + return eStringHolderEClass; + } + + /** + * + * + * @generated + */ + public EAttribute getEStringHolder_Value() { + return (EAttribute)eStringHolderEClass.getEStructuralFeatures().get(0); + } + + /** + * + * + * @generated + */ + public EClass getEObjectWithContainerId() { + return eObjectWithContainerIdEClass; + } + + /** + * + * + * @generated + */ + public EAttribute getEObjectWithContainerId_Id() { + return (EAttribute)eObjectWithContainerIdEClass.getEStructuralFeatures().get(0); + } + + /** + * + * + * @generated + */ + public EDataType getEJavaCollection() { + return eJavaCollectionEDataType; + } + + /** + * + * + * @generated + */ + public EDataType getEFile() { + return eFileEDataType; + } + + /** + * + * + * @generated + */ + public EDataType getEIterator() { + return eIteratorEDataType; + } + + /** + * + * + * @generated + */ + public CommonFactory getCommonFactory() { + return (CommonFactory)getEFactoryInstance(); + } + + /** + * + * + * @generated + */ + private boolean isCreated = false; + + /** + * Creates the meta-model objects for the package. This method is + * guarded to have no affect on any invocation but its first. + * + * + * @generated + */ + public void createPackageContents() { + if (isCreated) return; + isCreated = true; + + // Create classes and their features + eCollectionEClass = createEClass(ECOLLECTION); + createEReference(eCollectionEClass, ECOLLECTION__CONTENTS); + + ePairEClass = createEClass(EPAIR); + createEReference(ePairEClass, EPAIR__X); + createEReference(ePairEClass, EPAIR__Y); + + eRelationEClass = createEClass(ERELATION); + createEAttribute(eRelationEClass, ERELATION__NAME); + + eContainerEClass = createEClass(ECONTAINER); + createEReference(eContainerEClass, ECONTAINER__CONTAINEES); + + eNotContainerEClass = createEClass(ENOT_CONTAINER); + createEReference(eNotContainerEClass, ENOT_CONTAINER__ELEMENTS); + + eStringHolderEClass = createEClass(ESTRING_HOLDER); + createEAttribute(eStringHolderEClass, ESTRING_HOLDER__VALUE); + + eObjectWithContainerIdEClass = createEClass(EOBJECT_WITH_CONTAINER_ID); + createEAttribute(eObjectWithContainerIdEClass, EOBJECT_WITH_CONTAINER_ID__ID); + + // Create data types + eJavaCollectionEDataType = createEDataType(EJAVA_COLLECTION); + eFileEDataType = createEDataType(EFILE); + eIteratorEDataType = createEDataType(EITERATOR); + } + + /** + * + * + * @generated + */ + private boolean isInitialized = false; + + /** + * Complete the initialization of the package and its meta-model. This + * method is guarded to have no affect on any invocation but its first. + * + * + * @generated + */ + public void initializePackageContents() { + if (isInitialized) return; + isInitialized = true; + + // Initialize package + setName(eNAME); + setNsPrefix(eNS_PREFIX); + setNsURI(eNS_URI); + + // Add supertypes to classes + eRelationEClass.getESuperTypes().add(this.getEContainer()); + eContainerEClass.getESuperTypes().add(this.getECollection()); + eNotContainerEClass.getESuperTypes().add(this.getECollection()); + + // Initialize classes and features; add operations and parameters + initEClass(eCollectionEClass, ECollection.class, "ECollection", IS_ABSTRACT, IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); + initEReference(getECollection_Contents(), ecorePackage.getEObject(), null, "contents", null, 0, -1, ECollection.class, IS_TRANSIENT, IS_VOLATILE, IS_CHANGEABLE, !IS_COMPOSITE, IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); + + initEClass(ePairEClass, EPair.class, "EPair", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); + initEReference(getEPair_X(), ecorePackage.getEObject(), null, "X", null, 1, 1, EPair.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_COMPOSITE, IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); + initEReference(getEPair_Y(), ecorePackage.getEObject(), null, "Y", null, 1, 1, EPair.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_COMPOSITE, IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); + + initEClass(eRelationEClass, ERelation.class, "ERelation", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); + initEAttribute(getERelation_Name(), ecorePackage.getEString(), "name", null, 0, 1, ERelation.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); + + initEClass(eContainerEClass, EContainer.class, "EContainer", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); + initEReference(getEContainer_Containees(), ecorePackage.getEObject(), null, "containees", null, 0, -1, EContainer.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, IS_COMPOSITE, !IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); + + initEClass(eNotContainerEClass, ENotContainer.class, "ENotContainer", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); + initEReference(getENotContainer_Elements(), ecorePackage.getEObject(), null, "elements", null, 0, -1, ENotContainer.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_COMPOSITE, IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); + + initEClass(eStringHolderEClass, EStringHolder.class, "EStringHolder", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); + initEAttribute(getEStringHolder_Value(), ecorePackage.getEString(), "value", null, 1, 1, EStringHolder.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); + + initEClass(eObjectWithContainerIdEClass, EObjectWithContainerId.class, "EObjectWithContainerId", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); + initEAttribute(getEObjectWithContainerId_Id(), ecorePackage.getEInt(), "id", "-1", 1, 1, EObjectWithContainerId.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, IS_ID, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); + + // Initialize data types + initEDataType(eJavaCollectionEDataType, Collection.class, "EJavaCollection", !IS_SERIALIZABLE, !IS_GENERATED_INSTANCE_CLASS); + initEDataType(eFileEDataType, File.class, "EFile", !IS_SERIALIZABLE, !IS_GENERATED_INSTANCE_CLASS); + initEDataType(eIteratorEDataType, Iterator.class, "EIterator", !IS_SERIALIZABLE, !IS_GENERATED_INSTANCE_CLASS); + + // Create resource + createResource(eNS_URI); + } + +} //CommonPackageImpl diff --git a/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/common/impl/EContainerImpl.java b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/common/impl/EContainerImpl.java new file mode 100644 index 000000000..6abfa4ff2 --- /dev/null +++ b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/common/impl/EContainerImpl.java @@ -0,0 +1,165 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.common.impl; + +import java.util.Collection; + +import org.eclipse.emf.common.notify.NotificationChain; +import org.eclipse.emf.common.util.EList; +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.InternalEObject; +import org.eclipse.emf.ecore.impl.EObjectImpl; +import org.eclipse.emf.ecore.util.EObjectContainmentEList; +import org.eclipse.emf.ecore.util.InternalEList; + +import com.ibm.wala.ecore.common.CommonPackage; +import com.ibm.wala.ecore.common.EContainer; + +/** + * + * An implementation of the model object 'EContainer'. + * + *

                              + * The following features are implemented: + *

                                + *
                              • {@link com.ibm.wala.ecore.common.impl.EContainerImpl#getContents Contents}
                              • + *
                              • {@link com.ibm.wala.ecore.common.impl.EContainerImpl#getContainees Containees}
                              • + *
                              + *

                              + * + * @generated + */ +public class EContainerImpl extends EObjectImpl implements EContainer { + /** + * The cached value of the '{@link #getContainees() Containees}' containment reference list. + * + * + * @see #getContainees() + * @generated + * @ordered + */ + protected EList containees = null; + + /** + * + * + * @generated + */ + protected EContainerImpl() { + super(); + } + + /** + * + * + * @generated + */ + protected EClass eStaticClass() { + return CommonPackage.Literals.ECONTAINER; + } + + /** + * + * + */ + public EList getContents() { + return getContainees(); + } + + /** + * + * + * @generated + */ + public EList getContainees() { + if (containees == null) { + containees = new EObjectContainmentEList(EObject.class, this, CommonPackage.ECONTAINER__CONTAINEES); + } + return containees; + } + + /** + * + * + * @generated + */ + public NotificationChain eInverseRemove(InternalEObject otherEnd, int featureID, NotificationChain msgs) { + switch (featureID) { + case CommonPackage.ECONTAINER__CONTAINEES: + return ((InternalEList)getContainees()).basicRemove(otherEnd, msgs); + } + return super.eInverseRemove(otherEnd, featureID, msgs); + } + + /** + * + * + * @generated + */ + public Object eGet(int featureID, boolean resolve, boolean coreType) { + switch (featureID) { + case CommonPackage.ECONTAINER__CONTENTS: + return getContents(); + case CommonPackage.ECONTAINER__CONTAINEES: + return getContainees(); + } + return super.eGet(featureID, resolve, coreType); + } + + /** + * + * + * @generated + */ + public void eSet(int featureID, Object newValue) { + switch (featureID) { + case CommonPackage.ECONTAINER__CONTENTS: + getContents().clear(); + getContents().addAll((Collection)newValue); + return; + case CommonPackage.ECONTAINER__CONTAINEES: + getContainees().clear(); + getContainees().addAll((Collection)newValue); + return; + } + super.eSet(featureID, newValue); + } + + /** + * + * + * @generated + */ + public void eUnset(int featureID) { + switch (featureID) { + case CommonPackage.ECONTAINER__CONTENTS: + getContents().clear(); + return; + case CommonPackage.ECONTAINER__CONTAINEES: + getContainees().clear(); + return; + } + super.eUnset(featureID); + } + + /** + * + * + * @generated + */ + public boolean eIsSet(int featureID) { + switch (featureID) { + case CommonPackage.ECONTAINER__CONTENTS: + return !getContents().isEmpty(); + case CommonPackage.ECONTAINER__CONTAINEES: + return containees != null && !containees.isEmpty(); + } + return super.eIsSet(featureID); + } + +} //EContainerImpl \ No newline at end of file diff --git a/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/common/impl/ENotContainerImpl.java b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/common/impl/ENotContainerImpl.java new file mode 100644 index 000000000..c36c97ce5 --- /dev/null +++ b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/common/impl/ENotContainerImpl.java @@ -0,0 +1,150 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.common.impl; + +import com.ibm.wala.ecore.common.CommonPackage; +import com.ibm.wala.ecore.common.ENotContainer; + +import java.util.Collection; + +import org.eclipse.emf.common.util.EList; + +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EObject; + +import org.eclipse.emf.ecore.impl.EObjectImpl; + +import org.eclipse.emf.ecore.util.EObjectResolvingEList; + +/** + * + * An implementation of the model object 'ENot Container'. + * + *

                              + * The following features are implemented: + *

                                + *
                              • {@link com.ibm.wala.ecore.common.impl.ENotContainerImpl#getContents Contents}
                              • + *
                              • {@link com.ibm.wala.ecore.common.impl.ENotContainerImpl#getElements Elements}
                              • + *
                              + *

                              + * + * @generated + */ +public class ENotContainerImpl extends EObjectImpl implements ENotContainer { + /** + * The cached value of the '{@link #getElements() Elements}' reference list. + * + * + * @see #getElements() + * @generated + * @ordered + */ + protected EList elements = null; + + /** + * + * + * @generated + */ + protected ENotContainerImpl() { + super(); + } + + /** + * + * + * @generated + */ + protected EClass eStaticClass() { + return CommonPackage.Literals.ENOT_CONTAINER; + } + + /** + */ + public EList getContents() { + return getElements(); + } + + /** + * + * + * @generated + */ + public EList getElements() { + if (elements == null) { + elements = new EObjectResolvingEList(EObject.class, this, CommonPackage.ENOT_CONTAINER__ELEMENTS); + } + return elements; + } + + /** + * + * + * @generated + */ + public Object eGet(int featureID, boolean resolve, boolean coreType) { + switch (featureID) { + case CommonPackage.ENOT_CONTAINER__CONTENTS: + return getContents(); + case CommonPackage.ENOT_CONTAINER__ELEMENTS: + return getElements(); + } + return super.eGet(featureID, resolve, coreType); + } + + /** + * + * + * @generated + */ + public void eSet(int featureID, Object newValue) { + switch (featureID) { + case CommonPackage.ENOT_CONTAINER__CONTENTS: + getContents().clear(); + getContents().addAll((Collection)newValue); + return; + case CommonPackage.ENOT_CONTAINER__ELEMENTS: + getElements().clear(); + getElements().addAll((Collection)newValue); + return; + } + super.eSet(featureID, newValue); + } + + /** + * + * + * @generated + */ + public void eUnset(int featureID) { + switch (featureID) { + case CommonPackage.ENOT_CONTAINER__CONTENTS: + getContents().clear(); + return; + case CommonPackage.ENOT_CONTAINER__ELEMENTS: + getElements().clear(); + return; + } + super.eUnset(featureID); + } + + /** + * + * + * @generated + */ + public boolean eIsSet(int featureID) { + switch (featureID) { + case CommonPackage.ENOT_CONTAINER__CONTENTS: + return !getContents().isEmpty(); + case CommonPackage.ENOT_CONTAINER__ELEMENTS: + return elements != null && !elements.isEmpty(); + } + return super.eIsSet(featureID); + } + +} //ENotContainerImpl \ No newline at end of file diff --git a/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/common/impl/EObjectWithContainerIdImpl.java b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/common/impl/EObjectWithContainerIdImpl.java new file mode 100644 index 000000000..45dd0db2d --- /dev/null +++ b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/common/impl/EObjectWithContainerIdImpl.java @@ -0,0 +1,161 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.common.impl; + +import com.ibm.wala.ecore.common.CommonPackage; +import com.ibm.wala.ecore.common.EObjectWithContainerId; + +import org.eclipse.emf.common.notify.Notification; + +import org.eclipse.emf.ecore.EClass; + +import org.eclipse.emf.ecore.impl.ENotificationImpl; +import org.eclipse.emf.ecore.impl.EObjectImpl; + +/** + * + * An implementation of the model object 'EObject With Container Id'. + * + *

                              + * The following features are implemented: + *

                                + *
                              • {@link com.ibm.wala.ecore.common.impl.EObjectWithContainerIdImpl#getId Id}
                              • + *
                              + *

                              + * + * @generated + */ +public class EObjectWithContainerIdImpl extends EObjectImpl implements EObjectWithContainerId { + /** + * The default value of the '{@link #getId() Id}' attribute. + * + * + * @see #getId() + * @generated + * @ordered + */ + protected static final int ID_EDEFAULT = -1; + + /** + * The cached value of the '{@link #getId() Id}' attribute. + * + * + * @see #getId() + * @generated + * @ordered + */ + protected int id = ID_EDEFAULT; + + /** + * + * + * @generated + */ + protected EObjectWithContainerIdImpl() { + super(); + } + + /** + * + * + * @generated + */ + protected EClass eStaticClass() { + return CommonPackage.Literals.EOBJECT_WITH_CONTAINER_ID; + } + + /** + * + * + * @generated + */ + public int getId() { + return id; + } + + /** + * + * + * @generated + */ + public void setId(int newId) { + int oldId = id; + id = newId; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, CommonPackage.EOBJECT_WITH_CONTAINER_ID__ID, oldId, id)); + } + + /** + * + * + * @generated + */ + public Object eGet(int featureID, boolean resolve, boolean coreType) { + switch (featureID) { + case CommonPackage.EOBJECT_WITH_CONTAINER_ID__ID: + return new Integer(getId()); + } + return super.eGet(featureID, resolve, coreType); + } + + /** + * + * + * @generated + */ + public void eSet(int featureID, Object newValue) { + switch (featureID) { + case CommonPackage.EOBJECT_WITH_CONTAINER_ID__ID: + setId(((Integer)newValue).intValue()); + return; + } + super.eSet(featureID, newValue); + } + + /** + * + * + * @generated + */ + public void eUnset(int featureID) { + switch (featureID) { + case CommonPackage.EOBJECT_WITH_CONTAINER_ID__ID: + setId(ID_EDEFAULT); + return; + } + super.eUnset(featureID); + } + + /** + * + * + * @generated + */ + public boolean eIsSet(int featureID) { + switch (featureID) { + case CommonPackage.EOBJECT_WITH_CONTAINER_ID__ID: + return id != ID_EDEFAULT; + } + return super.eIsSet(featureID); + } + + /** + * + * + * @generated + */ + public String toString() { + if (eIsProxy()) return super.toString(); + + StringBuffer result = new StringBuffer(super.toString()); + result.append(" (id: "); + result.append(id); + result.append(')'); + return result.toString(); + } + +} //EObjectWithContainerIdImpl \ No newline at end of file diff --git a/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/common/impl/EPairImpl.java b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/common/impl/EPairImpl.java new file mode 100644 index 000000000..1c8113629 --- /dev/null +++ b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/common/impl/EPairImpl.java @@ -0,0 +1,216 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.common.impl; + +import com.ibm.wala.ecore.common.CommonPackage; +import com.ibm.wala.ecore.common.EPair; + +import org.eclipse.emf.common.notify.Notification; + +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.InternalEObject; + +import org.eclipse.emf.ecore.impl.ENotificationImpl; +import org.eclipse.emf.ecore.impl.EObjectImpl; + +/** + * + * An implementation of the model object 'EPair'. + * + *

                              + * The following features are implemented: + *

                                + *
                              • {@link com.ibm.wala.ecore.common.impl.EPairImpl#getX X}
                              • + *
                              • {@link com.ibm.wala.ecore.common.impl.EPairImpl#getY Y}
                              • + *
                              + *

                              + * + * @generated + */ +public class EPairImpl extends EObjectImpl implements EPair { + /** + * The cached value of the '{@link #getX() X}' reference. + * + * + * @see #getX() + * @generated + * @ordered + */ + protected EObject x = null; + + /** + * The cached value of the '{@link #getY() Y}' reference. + * + * + * @see #getY() + * @generated + * @ordered + */ + protected EObject y = null; + + /** + * + * + * @generated + */ + protected EPairImpl() { + super(); + } + + /** + * + * + * @generated + */ + protected EClass eStaticClass() { + return CommonPackage.Literals.EPAIR; + } + + /** + * + * + * @generated + */ + public EObject getX() { + if (x != null && x.eIsProxy()) { + InternalEObject oldX = (InternalEObject)x; + x = eResolveProxy(oldX); + if (x != oldX) { + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.RESOLVE, CommonPackage.EPAIR__X, oldX, x)); + } + } + return x; + } + + /** + * + * + * @generated + */ + public EObject basicGetX() { + return x; + } + + /** + * + * + * @generated + */ + public void setX(EObject newX) { + EObject oldX = x; + x = newX; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, CommonPackage.EPAIR__X, oldX, x)); + } + + /** + * + * + * @generated + */ + public EObject getY() { + if (y != null && y.eIsProxy()) { + InternalEObject oldY = (InternalEObject)y; + y = eResolveProxy(oldY); + if (y != oldY) { + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.RESOLVE, CommonPackage.EPAIR__Y, oldY, y)); + } + } + return y; + } + + /** + * + * + * @generated + */ + public EObject basicGetY() { + return y; + } + + /** + * + * + * @generated + */ + public void setY(EObject newY) { + EObject oldY = y; + y = newY; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, CommonPackage.EPAIR__Y, oldY, y)); + } + + /** + * + * + * @generated + */ + public Object eGet(int featureID, boolean resolve, boolean coreType) { + switch (featureID) { + case CommonPackage.EPAIR__X: + if (resolve) return getX(); + return basicGetX(); + case CommonPackage.EPAIR__Y: + if (resolve) return getY(); + return basicGetY(); + } + return super.eGet(featureID, resolve, coreType); + } + + /** + * + * + * @generated + */ + public void eSet(int featureID, Object newValue) { + switch (featureID) { + case CommonPackage.EPAIR__X: + setX((EObject)newValue); + return; + case CommonPackage.EPAIR__Y: + setY((EObject)newValue); + return; + } + super.eSet(featureID, newValue); + } + + /** + * + * + * @generated + */ + public void eUnset(int featureID) { + switch (featureID) { + case CommonPackage.EPAIR__X: + setX((EObject)null); + return; + case CommonPackage.EPAIR__Y: + setY((EObject)null); + return; + } + super.eUnset(featureID); + } + + /** + * + * + * @generated + */ + public boolean eIsSet(int featureID) { + switch (featureID) { + case CommonPackage.EPAIR__X: + return x != null; + case CommonPackage.EPAIR__Y: + return y != null; + } + return super.eIsSet(featureID); + } + +} //EPairImpl \ No newline at end of file diff --git a/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/common/impl/ERelationImpl.java b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/common/impl/ERelationImpl.java new file mode 100644 index 000000000..40ffa3b6d --- /dev/null +++ b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/common/impl/ERelationImpl.java @@ -0,0 +1,160 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.common.impl; + +import com.ibm.wala.ecore.common.CommonPackage; +import com.ibm.wala.ecore.common.ERelation; + +import org.eclipse.emf.common.notify.Notification; + +import org.eclipse.emf.ecore.EClass; + +import org.eclipse.emf.ecore.impl.ENotificationImpl; + +/** + * + * An implementation of the model object 'ERelation'. + * + *

                              + * The following features are implemented: + *

                                + *
                              • {@link com.ibm.wala.ecore.common.impl.ERelationImpl#getName Name}
                              • + *
                              + *

                              + * + * @generated + */ +public class ERelationImpl extends EContainerImpl implements ERelation { + /** + * The default value of the '{@link #getName() Name}' attribute. + * + * + * @see #getName() + * @generated + * @ordered + */ + protected static final String NAME_EDEFAULT = null; + + /** + * The cached value of the '{@link #getName() Name}' attribute. + * + * + * @see #getName() + * @generated + * @ordered + */ + protected String name = NAME_EDEFAULT; + + /** + * + * + * @generated + */ + protected ERelationImpl() { + super(); + } + + /** + * + * + * @generated + */ + protected EClass eStaticClass() { + return CommonPackage.Literals.ERELATION; + } + + /** + * + * + * @generated + */ + public String getName() { + return name; + } + + /** + * + * + * @generated + */ + public void setName(String newName) { + String oldName = name; + name = newName; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, CommonPackage.ERELATION__NAME, oldName, name)); + } + + /** + * + * + * @generated + */ + public Object eGet(int featureID, boolean resolve, boolean coreType) { + switch (featureID) { + case CommonPackage.ERELATION__NAME: + return getName(); + } + return super.eGet(featureID, resolve, coreType); + } + + /** + * + * + * @generated + */ + public void eSet(int featureID, Object newValue) { + switch (featureID) { + case CommonPackage.ERELATION__NAME: + setName((String)newValue); + return; + } + super.eSet(featureID, newValue); + } + + /** + * + * + * @generated + */ + public void eUnset(int featureID) { + switch (featureID) { + case CommonPackage.ERELATION__NAME: + setName(NAME_EDEFAULT); + return; + } + super.eUnset(featureID); + } + + /** + * + * + * @generated + */ + public boolean eIsSet(int featureID) { + switch (featureID) { + case CommonPackage.ERELATION__NAME: + return NAME_EDEFAULT == null ? name != null : !NAME_EDEFAULT.equals(name); + } + return super.eIsSet(featureID); + } + + /** + * + * + * @generated + */ + public String toString() { + if (eIsProxy()) return super.toString(); + + StringBuffer result = new StringBuffer(super.toString()); + result.append(" (name: "); + result.append(name); + result.append(')'); + return result.toString(); + } + +} //ERelationImpl \ No newline at end of file diff --git a/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/common/impl/EStringHolderImpl.java b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/common/impl/EStringHolderImpl.java new file mode 100644 index 000000000..ca900857e --- /dev/null +++ b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/common/impl/EStringHolderImpl.java @@ -0,0 +1,161 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.common.impl; + +import com.ibm.wala.ecore.common.CommonPackage; +import com.ibm.wala.ecore.common.EStringHolder; + +import org.eclipse.emf.common.notify.Notification; + +import org.eclipse.emf.ecore.EClass; + +import org.eclipse.emf.ecore.impl.ENotificationImpl; +import org.eclipse.emf.ecore.impl.EObjectImpl; + +/** + * + * An implementation of the model object 'EString Holder'. + * + *

                              + * The following features are implemented: + *

                                + *
                              • {@link com.ibm.wala.ecore.common.impl.EStringHolderImpl#getValue Value}
                              • + *
                              + *

                              + * + * @generated + */ +public class EStringHolderImpl extends EObjectImpl implements EStringHolder { + /** + * The default value of the '{@link #getValue() Value}' attribute. + * + * + * @see #getValue() + * @generated + * @ordered + */ + protected static final String VALUE_EDEFAULT = null; + + /** + * The cached value of the '{@link #getValue() Value}' attribute. + * + * + * @see #getValue() + * @generated + * @ordered + */ + protected String value = VALUE_EDEFAULT; + + /** + * + * + * @generated + */ + protected EStringHolderImpl() { + super(); + } + + /** + * + * + * @generated + */ + protected EClass eStaticClass() { + return CommonPackage.Literals.ESTRING_HOLDER; + } + + /** + * + * + * @generated + */ + public String getValue() { + return value; + } + + /** + * + * + * @generated + */ + public void setValue(String newValue) { + String oldValue = value; + value = newValue; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, CommonPackage.ESTRING_HOLDER__VALUE, oldValue, value)); + } + + /** + * + * + * @generated + */ + public Object eGet(int featureID, boolean resolve, boolean coreType) { + switch (featureID) { + case CommonPackage.ESTRING_HOLDER__VALUE: + return getValue(); + } + return super.eGet(featureID, resolve, coreType); + } + + /** + * + * + * @generated + */ + public void eSet(int featureID, Object newValue) { + switch (featureID) { + case CommonPackage.ESTRING_HOLDER__VALUE: + setValue((String)newValue); + return; + } + super.eSet(featureID, newValue); + } + + /** + * + * + * @generated + */ + public void eUnset(int featureID) { + switch (featureID) { + case CommonPackage.ESTRING_HOLDER__VALUE: + setValue(VALUE_EDEFAULT); + return; + } + super.eUnset(featureID); + } + + /** + * + * + * @generated + */ + public boolean eIsSet(int featureID) { + switch (featureID) { + case CommonPackage.ESTRING_HOLDER__VALUE: + return VALUE_EDEFAULT == null ? value != null : !VALUE_EDEFAULT.equals(value); + } + return super.eIsSet(featureID); + } + + /** + * + * + * @generated + */ + public String toString() { + if (eIsProxy()) return super.toString(); + + StringBuffer result = new StringBuffer(super.toString()); + result.append(" (value: "); + result.append(value); + result.append(')'); + return result.toString(); + } + +} //EStringHolderImpl \ No newline at end of file diff --git a/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/common/util/CommonAdapterFactory.java b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/common/util/CommonAdapterFactory.java new file mode 100644 index 000000000..a9ac7b5d7 --- /dev/null +++ b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/common/util/CommonAdapterFactory.java @@ -0,0 +1,222 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.common.util; + +import com.ibm.wala.ecore.common.*; + +import org.eclipse.emf.common.notify.Adapter; +import org.eclipse.emf.common.notify.Notifier; + +import org.eclipse.emf.common.notify.impl.AdapterFactoryImpl; + +import org.eclipse.emf.ecore.EObject; + +/** + * + * The Adapter Factory for the model. + * It provides an adapter createXXX method for each class of the model. + * + * @see com.ibm.wala.ecore.common.CommonPackage + * @generated + */ +public class CommonAdapterFactory extends AdapterFactoryImpl { + /** + * The cached model package. + * + * + * @generated + */ + protected static CommonPackage modelPackage; + + /** + * Creates an instance of the adapter factory. + * + * + * @generated + */ + public CommonAdapterFactory() { + if (modelPackage == null) { + modelPackage = CommonPackage.eINSTANCE; + } + } + + /** + * Returns whether this factory is applicable for the type of the object. + * + * This implementation returns true if the object is either the model's package or is an instance object of the model. + * + * @return whether this factory is applicable for the type of the object. + * @generated + */ + public boolean isFactoryForType(Object object) { + if (object == modelPackage) { + return true; + } + if (object instanceof EObject) { + return ((EObject)object).eClass().getEPackage() == modelPackage; + } + return false; + } + + /** + * The switch the delegates to the createXXX methods. + * + * + * @generated + */ + protected CommonSwitch modelSwitch = + new CommonSwitch() { + public Object caseECollection(ECollection object) { + return createECollectionAdapter(); + } + public Object caseEPair(EPair object) { + return createEPairAdapter(); + } + public Object caseERelation(ERelation object) { + return createERelationAdapter(); + } + public Object caseEContainer(EContainer object) { + return createEContainerAdapter(); + } + public Object caseENotContainer(ENotContainer object) { + return createENotContainerAdapter(); + } + public Object caseEStringHolder(EStringHolder object) { + return createEStringHolderAdapter(); + } + public Object caseEObjectWithContainerId(EObjectWithContainerId object) { + return createEObjectWithContainerIdAdapter(); + } + public Object defaultCase(EObject object) { + return createEObjectAdapter(); + } + }; + + /** + * Creates an adapter for the target. + * + * + * @param target the object to adapt. + * @return the adapter for the target. + * @generated + */ + public Adapter createAdapter(Notifier target) { + return (Adapter)modelSwitch.doSwitch((EObject)target); + } + + + /** + * Creates a new adapter for an object of class '{@link com.ibm.wala.ecore.common.ECollection ECollection}'. + * + * This default implementation returns null so that we can easily ignore cases; + * it's useful to ignore a case when inheritance will catch all the cases anyway. + * + * @return the new adapter. + * @see com.ibm.wala.ecore.common.ECollection + * @generated + */ + public Adapter createECollectionAdapter() { + return null; + } + + /** + * Creates a new adapter for an object of class '{@link com.ibm.wala.ecore.common.EPair EPair}'. + * + * This default implementation returns null so that we can easily ignore cases; + * it's useful to ignore a case when inheritance will catch all the cases anyway. + * + * @return the new adapter. + * @see com.ibm.wala.ecore.common.EPair + * @generated + */ + public Adapter createEPairAdapter() { + return null; + } + + /** + * Creates a new adapter for an object of class '{@link com.ibm.wala.ecore.common.ERelation ERelation}'. + * + * This default implementation returns null so that we can easily ignore cases; + * it's useful to ignore a case when inheritance will catch all the cases anyway. + * + * @return the new adapter. + * @see com.ibm.wala.ecore.common.ERelation + * @generated + */ + public Adapter createERelationAdapter() { + return null; + } + + /** + * Creates a new adapter for an object of class '{@link com.ibm.wala.ecore.common.EContainer EContainer}'. + * + * This default implementation returns null so that we can easily ignore cases; + * it's useful to ignore a case when inheritance will catch all the cases anyway. + * + * @return the new adapter. + * @see com.ibm.wala.ecore.common.EContainer + * @generated + */ + public Adapter createEContainerAdapter() { + return null; + } + + /** + * Creates a new adapter for an object of class '{@link com.ibm.wala.ecore.common.ENotContainer ENot Container}'. + * + * This default implementation returns null so that we can easily ignore cases; + * it's useful to ignore a case when inheritance will catch all the cases anyway. + * + * @return the new adapter. + * @see com.ibm.wala.ecore.common.ENotContainer + * @generated + */ + public Adapter createENotContainerAdapter() { + return null; + } + + /** + * Creates a new adapter for an object of class '{@link com.ibm.wala.ecore.common.EStringHolder EString Holder}'. + * + * This default implementation returns null so that we can easily ignore cases; + * it's useful to ignore a case when inheritance will catch all the cases anyway. + * + * @return the new adapter. + * @see com.ibm.wala.ecore.common.EStringHolder + * @generated + */ + public Adapter createEStringHolderAdapter() { + return null; + } + + /** + * Creates a new adapter for an object of class '{@link com.ibm.wala.ecore.common.EObjectWithContainerId EObject With Container Id}'. + * + * This default implementation returns null so that we can easily ignore cases; + * it's useful to ignore a case when inheritance will catch all the cases anyway. + * + * @return the new adapter. + * @see com.ibm.wala.ecore.common.EObjectWithContainerId + * @generated + */ + public Adapter createEObjectWithContainerIdAdapter() { + return null; + } + + /** + * Creates a new adapter for the default case. + * + * This default implementation returns null. + * + * @return the new adapter. + * @generated + */ + public Adapter createEObjectAdapter() { + return null; + } + +} //CommonAdapterFactory diff --git a/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/common/util/CommonSwitch.java b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/common/util/CommonSwitch.java new file mode 100644 index 000000000..6af576926 --- /dev/null +++ b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/common/util/CommonSwitch.java @@ -0,0 +1,260 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.common.util; + +import com.ibm.wala.ecore.common.*; + +import java.util.List; + +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EObject; + +/** + * + * The Switch for the model's inheritance hierarchy. + * It supports the call {@link #doSwitch(EObject) doSwitch(object)} + * to invoke the caseXXX method for each class of the model, + * starting with the actual class of the object + * and proceeding up the inheritance hierarchy + * until a non-null result is returned, + * which is the result of the switch. + * + * @see com.ibm.wala.ecore.common.CommonPackage + * @generated + */ +public class CommonSwitch { + /** + * The cached model package + * + * + * @generated + */ + protected static CommonPackage modelPackage; + + /** + * Creates an instance of the switch. + * + * + * @generated + */ + public CommonSwitch() { + if (modelPackage == null) { + modelPackage = CommonPackage.eINSTANCE; + } + } + + /** + * Calls caseXXX for each class of the model until one returns a non null result; it yields that result. + * + * + * @return the first non-null result returned by a caseXXX call. + * @generated + */ + public Object doSwitch(EObject theEObject) { + return doSwitch(theEObject.eClass(), theEObject); + } + + /** + * Calls caseXXX for each class of the model until one returns a non null result; it yields that result. + * + * + * @return the first non-null result returned by a caseXXX call. + * @generated + */ + protected Object doSwitch(EClass theEClass, EObject theEObject) { + if (theEClass.eContainer() == modelPackage) { + return doSwitch(theEClass.getClassifierID(), theEObject); + } + else { + List eSuperTypes = theEClass.getESuperTypes(); + return + eSuperTypes.isEmpty() ? + defaultCase(theEObject) : + doSwitch((EClass)eSuperTypes.get(0), theEObject); + } + } + + /** + * Calls caseXXX for each class of the model until one returns a non null result; it yields that result. + * + * + * @return the first non-null result returned by a caseXXX call. + * @generated + */ + protected Object doSwitch(int classifierID, EObject theEObject) { + switch (classifierID) { + case CommonPackage.ECOLLECTION: { + ECollection eCollection = (ECollection)theEObject; + Object result = caseECollection(eCollection); + if (result == null) result = defaultCase(theEObject); + return result; + } + case CommonPackage.EPAIR: { + EPair ePair = (EPair)theEObject; + Object result = caseEPair(ePair); + if (result == null) result = defaultCase(theEObject); + return result; + } + case CommonPackage.ERELATION: { + ERelation eRelation = (ERelation)theEObject; + Object result = caseERelation(eRelation); + if (result == null) result = caseEContainer(eRelation); + if (result == null) result = caseECollection(eRelation); + if (result == null) result = defaultCase(theEObject); + return result; + } + case CommonPackage.ECONTAINER: { + EContainer eContainer = (EContainer)theEObject; + Object result = caseEContainer(eContainer); + if (result == null) result = caseECollection(eContainer); + if (result == null) result = defaultCase(theEObject); + return result; + } + case CommonPackage.ENOT_CONTAINER: { + ENotContainer eNotContainer = (ENotContainer)theEObject; + Object result = caseENotContainer(eNotContainer); + if (result == null) result = caseECollection(eNotContainer); + if (result == null) result = defaultCase(theEObject); + return result; + } + case CommonPackage.ESTRING_HOLDER: { + EStringHolder eStringHolder = (EStringHolder)theEObject; + Object result = caseEStringHolder(eStringHolder); + if (result == null) result = defaultCase(theEObject); + return result; + } + case CommonPackage.EOBJECT_WITH_CONTAINER_ID: { + EObjectWithContainerId eObjectWithContainerId = (EObjectWithContainerId)theEObject; + Object result = caseEObjectWithContainerId(eObjectWithContainerId); + if (result == null) result = defaultCase(theEObject); + return result; + } + default: return defaultCase(theEObject); + } + } + + /** + * Returns the result of interpretting the object as an instance of 'ECollection'. + * + * This implementation returns null; + * returning a non-null result will terminate the switch. + * + * @param object the target of the switch. + * @return the result of interpretting the object as an instance of 'ECollection'. + * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject) + * @generated + */ + public Object caseECollection(ECollection object) { + return null; + } + + /** + * Returns the result of interpretting the object as an instance of 'EPair'. + * + * This implementation returns null; + * returning a non-null result will terminate the switch. + * + * @param object the target of the switch. + * @return the result of interpretting the object as an instance of 'EPair'. + * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject) + * @generated + */ + public Object caseEPair(EPair object) { + return null; + } + + /** + * Returns the result of interpretting the object as an instance of 'ERelation'. + * + * This implementation returns null; + * returning a non-null result will terminate the switch. + * + * @param object the target of the switch. + * @return the result of interpretting the object as an instance of 'ERelation'. + * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject) + * @generated + */ + public Object caseERelation(ERelation object) { + return null; + } + + /** + * Returns the result of interpretting the object as an instance of 'EContainer'. + * + * This implementation returns null; + * returning a non-null result will terminate the switch. + * + * @param object the target of the switch. + * @return the result of interpretting the object as an instance of 'EContainer'. + * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject) + * @generated + */ + public Object caseEContainer(EContainer object) { + return null; + } + + /** + * Returns the result of interpretting the object as an instance of 'ENot Container'. + * + * This implementation returns null; + * returning a non-null result will terminate the switch. + * + * @param object the target of the switch. + * @return the result of interpretting the object as an instance of 'ENot Container'. + * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject) + * @generated + */ + public Object caseENotContainer(ENotContainer object) { + return null; + } + + /** + * Returns the result of interpretting the object as an instance of 'EString Holder'. + * + * This implementation returns null; + * returning a non-null result will terminate the switch. + * + * @param object the target of the switch. + * @return the result of interpretting the object as an instance of 'EString Holder'. + * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject) + * @generated + */ + public Object caseEStringHolder(EStringHolder object) { + return null; + } + + /** + * Returns the result of interpretting the object as an instance of 'EObject With Container Id'. + * + * This implementation returns null; + * returning a non-null result will terminate the switch. + * + * @param object the target of the switch. + * @return the result of interpretting the object as an instance of 'EObject With Container Id'. + * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject) + * @generated + */ + public Object caseEObjectWithContainerId(EObjectWithContainerId object) { + return null; + } + + /** + * Returns the result of interpretting the object as an instance of 'EObject'. + * + * This implementation returns null; + * returning a non-null result will terminate the switch, but this is the last case anyway. + * + * @param object the target of the switch. + * @return the result of interpretting the object as an instance of 'EObject'. + * @see #doSwitch(org.eclipse.emf.ecore.EObject) + * @generated + */ + public Object defaultCase(EObject object) { + return null; + } + +} //CommonSwitch diff --git a/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/graph/EGraph.java b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/graph/EGraph.java new file mode 100644 index 000000000..4ace2b637 --- /dev/null +++ b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/graph/EGraph.java @@ -0,0 +1,84 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.graph; + +import com.ibm.wala.ecore.common.ECollection; +import com.ibm.wala.ecore.common.ERelation; + +import org.eclipse.emf.ecore.EObject; + +/** + * + * A representation of the model object 'EGraph'. + * + * + *

                              + * The following features are supported: + *

                                + *
                              • {@link com.ibm.wala.ecore.graph.EGraph#getNodes Nodes}
                              • + *
                              • {@link com.ibm.wala.ecore.graph.EGraph#getEdges Edges}
                              • + *
                              + *

                              + * + * @see com.ibm.wala.ecore.graph.GraphPackage#getEGraph() + * @model + * @generated + */ +public interface EGraph extends EObject { + /** + * Returns the value of the 'Nodes' reference. + * + *

                              + * If the meaning of the 'Nodes' reference isn't clear, + * there really should be more of a description here... + *

                              + * + * @return the value of the 'Nodes' reference. + * @see #setNodes(ECollection) + * @see com.ibm.wala.ecore.graph.GraphPackage#getEGraph_Nodes() + * @model required="true" + * @generated + */ + ECollection getNodes(); + + /** + * Sets the value of the '{@link com.ibm.wala.ecore.graph.EGraph#getNodes Nodes}' reference. + * + * + * @param value the new value of the 'Nodes' reference. + * @see #getNodes() + * @generated + */ + void setNodes(ECollection value); + + /** + * Returns the value of the 'Edges' containment reference. + * + *

                              + * If the meaning of the 'Edges' containment reference isn't clear, + * there really should be more of a description here... + *

                              + * + * @return the value of the 'Edges' containment reference. + * @see #setEdges(ERelation) + * @see com.ibm.wala.ecore.graph.GraphPackage#getEGraph_Edges() + * @model containment="true" required="true" + * @generated + */ + ERelation getEdges(); + + /** + * Sets the value of the '{@link com.ibm.wala.ecore.graph.EGraph#getEdges Edges}' containment reference. + * + * + * @param value the new value of the 'Edges' containment reference. + * @see #getEdges() + * @generated + */ + void setEdges(ERelation value); + +} // EGraph \ No newline at end of file diff --git a/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/graph/ETree.java b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/graph/ETree.java new file mode 100644 index 000000000..a2f475098 --- /dev/null +++ b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/graph/ETree.java @@ -0,0 +1,21 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.graph; + + +/** + * + * A representation of the model object 'ETree'. + * + * + * + * @see com.ibm.wala.ecore.graph.GraphPackage#getETree() + * @model + * @generated + */ +public interface ETree extends EGraph { +} // ETree \ No newline at end of file diff --git a/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/graph/GraphFactory.java b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/graph/GraphFactory.java new file mode 100644 index 000000000..90b42e92d --- /dev/null +++ b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/graph/GraphFactory.java @@ -0,0 +1,55 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.graph; + +import org.eclipse.emf.ecore.EFactory; + +/** + * + * The Factory for the model. + * It provides a create method for each non-abstract class of the model. + * + * @see com.ibm.wala.ecore.graph.GraphPackage + * @generated + */ +public interface GraphFactory extends EFactory { + /** + * The singleton instance of the factory. + * + * + * @generated + */ + GraphFactory eINSTANCE = com.ibm.wala.ecore.graph.impl.GraphFactoryImpl.init(); + + /** + * Returns a new object of class 'EGraph'. + * + * + * @return a new object of class 'EGraph'. + * @generated + */ + EGraph createEGraph(); + + /** + * Returns a new object of class 'ETree'. + * + * + * @return a new object of class 'ETree'. + * @generated + */ + ETree createETree(); + + /** + * Returns the package supported by this factory. + * + * + * @return the package supported by this factory. + * @generated + */ + GraphPackage getGraphPackage(); + +} //GraphFactory diff --git a/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/graph/GraphPackage.java b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/graph/GraphPackage.java new file mode 100644 index 000000000..a12bb5aa5 --- /dev/null +++ b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/graph/GraphPackage.java @@ -0,0 +1,238 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.graph; + +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EPackage; +import org.eclipse.emf.ecore.EReference; + +/** + * + * The Package for the model. + * It contains accessors for the meta objects to represent + *
                                + *
                              • each class,
                              • + *
                              • each feature of each class,
                              • + *
                              • each enum,
                              • + *
                              • and each data type
                              • + *
                              + * + * @see com.ibm.wala.ecore.graph.GraphFactory + * @model kind="package" + * @generated + */ +public interface GraphPackage extends EPackage { + /** + * The package name. + * + * + * @generated + */ + String eNAME = "graph"; + + /** + * The package namespace URI. + * + * + * @generated + */ + String eNS_URI = "http:///com/ibm/wala/wala.ecore.graph"; + + /** + * The package namespace name. + * + * + * @generated + */ + String eNS_PREFIX = "com.ibm.wala.graph"; + + /** + * The singleton instance of the package. + * + * + * @generated + */ + GraphPackage eINSTANCE = com.ibm.wala.ecore.graph.impl.GraphPackageImpl.init(); + + /** + * The meta object id for the '{@link com.ibm.wala.ecore.graph.impl.EGraphImpl EGraph}' class. + * + * + * @see com.ibm.wala.ecore.graph.impl.EGraphImpl + * @see com.ibm.wala.ecore.graph.impl.GraphPackageImpl#getEGraph() + * @generated + */ + int EGRAPH = 0; + + /** + * The feature id for the 'Nodes' reference. + * + * + * @generated + * @ordered + */ + int EGRAPH__NODES = 0; + + /** + * The feature id for the 'Edges' containment reference. + * + * + * @generated + * @ordered + */ + int EGRAPH__EDGES = 1; + + /** + * The number of structural features of the 'EGraph' class. + * + * + * @generated + * @ordered + */ + int EGRAPH_FEATURE_COUNT = 2; + + /** + * The meta object id for the '{@link com.ibm.wala.ecore.graph.impl.ETreeImpl ETree}' class. + * + * + * @see com.ibm.wala.ecore.graph.impl.ETreeImpl + * @see com.ibm.wala.ecore.graph.impl.GraphPackageImpl#getETree() + * @generated + */ + int ETREE = 1; + + /** + * The feature id for the 'Nodes' reference. + * + * + * @generated + * @ordered + */ + int ETREE__NODES = EGRAPH__NODES; + + /** + * The feature id for the 'Edges' containment reference. + * + * + * @generated + * @ordered + */ + int ETREE__EDGES = EGRAPH__EDGES; + + /** + * The number of structural features of the 'ETree' class. + * + * + * @generated + * @ordered + */ + int ETREE_FEATURE_COUNT = EGRAPH_FEATURE_COUNT + 0; + + + /** + * Returns the meta object for class '{@link com.ibm.wala.ecore.graph.EGraph EGraph}'. + * + * + * @return the meta object for class 'EGraph'. + * @see com.ibm.wala.ecore.graph.EGraph + * @generated + */ + EClass getEGraph(); + + /** + * Returns the meta object for the reference '{@link com.ibm.wala.ecore.graph.EGraph#getNodes Nodes}'. + * + * + * @return the meta object for the reference 'Nodes'. + * @see com.ibm.wala.ecore.graph.EGraph#getNodes() + * @see #getEGraph() + * @generated + */ + EReference getEGraph_Nodes(); + + /** + * Returns the meta object for the containment reference '{@link com.ibm.wala.ecore.graph.EGraph#getEdges Edges}'. + * + * + * @return the meta object for the containment reference 'Edges'. + * @see com.ibm.wala.ecore.graph.EGraph#getEdges() + * @see #getEGraph() + * @generated + */ + EReference getEGraph_Edges(); + + /** + * Returns the meta object for class '{@link com.ibm.wala.ecore.graph.ETree ETree}'. + * + * + * @return the meta object for class 'ETree'. + * @see com.ibm.wala.ecore.graph.ETree + * @generated + */ + EClass getETree(); + + /** + * Returns the factory that creates the instances of the model. + * + * + * @return the factory that creates the instances of the model. + * @generated + */ + GraphFactory getGraphFactory(); + + /** + * + * Defines literals for the meta objects that represent + *
                                + *
                              • each class,
                              • + *
                              • each feature of each class,
                              • + *
                              • each enum,
                              • + *
                              • and each data type
                              • + *
                              + * + * @generated + */ + interface Literals { + /** + * The meta object literal for the '{@link com.ibm.wala.ecore.graph.impl.EGraphImpl EGraph}' class. + * + * + * @see com.ibm.wala.ecore.graph.impl.EGraphImpl + * @see com.ibm.wala.ecore.graph.impl.GraphPackageImpl#getEGraph() + * @generated + */ + EClass EGRAPH = eINSTANCE.getEGraph(); + + /** + * The meta object literal for the 'Nodes' reference feature. + * + * + * @generated + */ + EReference EGRAPH__NODES = eINSTANCE.getEGraph_Nodes(); + + /** + * The meta object literal for the 'Edges' containment reference feature. + * + * + * @generated + */ + EReference EGRAPH__EDGES = eINSTANCE.getEGraph_Edges(); + + /** + * The meta object literal for the '{@link com.ibm.wala.ecore.graph.impl.ETreeImpl ETree}' class. + * + * + * @see com.ibm.wala.ecore.graph.impl.ETreeImpl + * @see com.ibm.wala.ecore.graph.impl.GraphPackageImpl#getETree() + * @generated + */ + EClass ETREE = eINSTANCE.getETree(); + + } + +} //GraphPackage diff --git a/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/graph/impl/EGraphImpl.java b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/graph/impl/EGraphImpl.java new file mode 100644 index 000000000..17d2d3c24 --- /dev/null +++ b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/graph/impl/EGraphImpl.java @@ -0,0 +1,236 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.graph.impl; + +import com.ibm.wala.ecore.common.ECollection; +import com.ibm.wala.ecore.common.ERelation; + +import com.ibm.wala.ecore.graph.EGraph; +import com.ibm.wala.ecore.graph.GraphPackage; + +import org.eclipse.emf.common.notify.Notification; +import org.eclipse.emf.common.notify.NotificationChain; + +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.InternalEObject; + +import org.eclipse.emf.ecore.impl.ENotificationImpl; +import org.eclipse.emf.ecore.impl.EObjectImpl; + +/** + * + * An implementation of the model object 'EGraph'. + * + *

                              + * The following features are implemented: + *

                                + *
                              • {@link com.ibm.wala.ecore.graph.impl.EGraphImpl#getNodes Nodes}
                              • + *
                              • {@link com.ibm.wala.ecore.graph.impl.EGraphImpl#getEdges Edges}
                              • + *
                              + *

                              + * + * @generated + */ +public class EGraphImpl extends EObjectImpl implements EGraph { + /** + * The cached value of the '{@link #getNodes() Nodes}' reference. + * + * + * @see #getNodes() + * @generated + * @ordered + */ + protected ECollection nodes = null; + + /** + * The cached value of the '{@link #getEdges() Edges}' containment reference. + * + * + * @see #getEdges() + * @generated + * @ordered + */ + protected ERelation edges = null; + + /** + * + * + * @generated + */ + protected EGraphImpl() { + super(); + } + + /** + * + * + * @generated + */ + protected EClass eStaticClass() { + return GraphPackage.Literals.EGRAPH; + } + + /** + * + * + * @generated + */ + public ECollection getNodes() { + if (nodes != null && nodes.eIsProxy()) { + InternalEObject oldNodes = (InternalEObject)nodes; + nodes = (ECollection)eResolveProxy(oldNodes); + if (nodes != oldNodes) { + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.RESOLVE, GraphPackage.EGRAPH__NODES, oldNodes, nodes)); + } + } + return nodes; + } + + /** + * + * + * @generated + */ + public ECollection basicGetNodes() { + return nodes; + } + + /** + * + * + * @generated + */ + public void setNodes(ECollection newNodes) { + ECollection oldNodes = nodes; + nodes = newNodes; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, GraphPackage.EGRAPH__NODES, oldNodes, nodes)); + } + + /** + * + * + * @generated + */ + public ERelation getEdges() { + return edges; + } + + /** + * + * + * @generated + */ + public NotificationChain basicSetEdges(ERelation newEdges, NotificationChain msgs) { + ERelation oldEdges = edges; + edges = newEdges; + if (eNotificationRequired()) { + ENotificationImpl notification = new ENotificationImpl(this, Notification.SET, GraphPackage.EGRAPH__EDGES, oldEdges, newEdges); + if (msgs == null) msgs = notification; else msgs.add(notification); + } + return msgs; + } + + /** + * + * + * @generated + */ + public void setEdges(ERelation newEdges) { + if (newEdges != edges) { + NotificationChain msgs = null; + if (edges != null) + msgs = ((InternalEObject)edges).eInverseRemove(this, EOPPOSITE_FEATURE_BASE - GraphPackage.EGRAPH__EDGES, null, msgs); + if (newEdges != null) + msgs = ((InternalEObject)newEdges).eInverseAdd(this, EOPPOSITE_FEATURE_BASE - GraphPackage.EGRAPH__EDGES, null, msgs); + msgs = basicSetEdges(newEdges, msgs); + if (msgs != null) msgs.dispatch(); + } + else if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, GraphPackage.EGRAPH__EDGES, newEdges, newEdges)); + } + + /** + * + * + * @generated + */ + public NotificationChain eInverseRemove(InternalEObject otherEnd, int featureID, NotificationChain msgs) { + switch (featureID) { + case GraphPackage.EGRAPH__EDGES: + return basicSetEdges(null, msgs); + } + return super.eInverseRemove(otherEnd, featureID, msgs); + } + + /** + * + * + * @generated + */ + public Object eGet(int featureID, boolean resolve, boolean coreType) { + switch (featureID) { + case GraphPackage.EGRAPH__NODES: + if (resolve) return getNodes(); + return basicGetNodes(); + case GraphPackage.EGRAPH__EDGES: + return getEdges(); + } + return super.eGet(featureID, resolve, coreType); + } + + /** + * + * + * @generated + */ + public void eSet(int featureID, Object newValue) { + switch (featureID) { + case GraphPackage.EGRAPH__NODES: + setNodes((ECollection)newValue); + return; + case GraphPackage.EGRAPH__EDGES: + setEdges((ERelation)newValue); + return; + } + super.eSet(featureID, newValue); + } + + /** + * + * + * @generated + */ + public void eUnset(int featureID) { + switch (featureID) { + case GraphPackage.EGRAPH__NODES: + setNodes((ECollection)null); + return; + case GraphPackage.EGRAPH__EDGES: + setEdges((ERelation)null); + return; + } + super.eUnset(featureID); + } + + /** + * + * + * @generated + */ + public boolean eIsSet(int featureID) { + switch (featureID) { + case GraphPackage.EGRAPH__NODES: + return nodes != null; + case GraphPackage.EGRAPH__EDGES: + return edges != null; + } + return super.eIsSet(featureID); + } + +} //EGraphImpl \ No newline at end of file diff --git a/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/graph/impl/ETreeImpl.java b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/graph/impl/ETreeImpl.java new file mode 100644 index 000000000..45b9e97fc --- /dev/null +++ b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/graph/impl/ETreeImpl.java @@ -0,0 +1,42 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.graph.impl; + +import com.ibm.wala.ecore.graph.ETree; +import com.ibm.wala.ecore.graph.GraphPackage; + +import org.eclipse.emf.ecore.EClass; + +/** + * + * An implementation of the model object 'ETree'. + * + *

                              + *

                              + * + * @generated + */ +public class ETreeImpl extends EGraphImpl implements ETree { + /** + * + * + * @generated + */ + protected ETreeImpl() { + super(); + } + + /** + * + * + * @generated + */ + protected EClass eStaticClass() { + return GraphPackage.Literals.ETREE; + } + +} //ETreeImpl \ No newline at end of file diff --git a/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/graph/impl/GraphFactoryImpl.java b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/graph/impl/GraphFactoryImpl.java new file mode 100644 index 000000000..7b4e5867e --- /dev/null +++ b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/graph/impl/GraphFactoryImpl.java @@ -0,0 +1,108 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.graph.impl; + +import com.ibm.wala.ecore.graph.*; + +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EPackage; + +import org.eclipse.emf.ecore.impl.EFactoryImpl; + +import org.eclipse.emf.ecore.plugin.EcorePlugin; + +/** + * + * An implementation of the model Factory. + * + * @generated + */ +public class GraphFactoryImpl extends EFactoryImpl implements GraphFactory { + /** + * Creates the default factory implementation. + * + * + * @generated + */ + public static GraphFactory init() { + try { + GraphFactory theGraphFactory = (GraphFactory)EPackage.Registry.INSTANCE.getEFactory("http:///com/ibm/wala/wala.ecore.graph"); + if (theGraphFactory != null) { + return theGraphFactory; + } + } + catch (Exception exception) { + EcorePlugin.INSTANCE.log(exception); + } + return new GraphFactoryImpl(); + } + + /** + * Creates an instance of the factory. + * + * + * @generated + */ + public GraphFactoryImpl() { + super(); + } + + /** + * + * + * @generated + */ + public EObject create(EClass eClass) { + switch (eClass.getClassifierID()) { + case GraphPackage.EGRAPH: return createEGraph(); + case GraphPackage.ETREE: return createETree(); + default: + throw new IllegalArgumentException("The class '" + eClass.getName() + "' is not a valid classifier"); + } + } + + /** + * + * + * @generated + */ + public EGraph createEGraph() { + EGraphImpl eGraph = new EGraphImpl(); + return eGraph; + } + + /** + * + * + * @generated + */ + public ETree createETree() { + ETreeImpl eTree = new ETreeImpl(); + return eTree; + } + + /** + * + * + * @generated + */ + public GraphPackage getGraphPackage() { + return (GraphPackage)getEPackage(); + } + + /** + * + * + * @deprecated + * @generated + */ + public static GraphPackage getPackage() { + return GraphPackage.eINSTANCE; + } + +} //GraphFactoryImpl diff --git a/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/graph/impl/GraphPackageImpl.java b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/graph/impl/GraphPackageImpl.java new file mode 100644 index 000000000..0e51721f3 --- /dev/null +++ b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/graph/impl/GraphPackageImpl.java @@ -0,0 +1,278 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.graph.impl; + +import com.ibm.wala.ecore.common.CommonPackage; + +import com.ibm.wala.ecore.common.impl.CommonPackageImpl; + +import com.ibm.wala.ecore.graph.EGraph; +import com.ibm.wala.ecore.graph.ETree; +import com.ibm.wala.ecore.graph.GraphFactory; +import com.ibm.wala.ecore.graph.GraphPackage; + +import com.ibm.wala.ecore.j2ee.scope.J2EEScopePackage; + +import com.ibm.wala.ecore.j2ee.scope.impl.J2EEScopePackageImpl; + +import com.ibm.wala.ecore.java.JavaPackage; + +import com.ibm.wala.ecore.java.callGraph.CallGraphPackage; + +import com.ibm.wala.ecore.java.callGraph.impl.CallGraphPackageImpl; + +import com.ibm.wala.ecore.java.impl.JavaPackageImpl; + +import com.ibm.wala.ecore.java.pointerAnalysis.PointerAnalysisPackage; + +import com.ibm.wala.ecore.java.pointerAnalysis.impl.PointerAnalysisPackageImpl; + +import com.ibm.wala.ecore.java.scope.JavaScopePackage; + +import com.ibm.wala.ecore.java.scope.impl.JavaScopePackageImpl; + +import com.ibm.wala.ecore.perf.PerfPackage; + +import com.ibm.wala.ecore.perf.impl.PerfPackageImpl; + +import com.ibm.wala.ecore.regex.RegexPackage; + +import com.ibm.wala.ecore.regex.impl.RegexPackageImpl; + +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EPackage; +import org.eclipse.emf.ecore.EReference; + +import org.eclipse.emf.ecore.impl.EPackageImpl; + +/** + * + * An implementation of the model Package. + * + * @generated + */ +public class GraphPackageImpl extends EPackageImpl implements GraphPackage { + /** + * + * + * @generated + */ + private EClass eGraphEClass = null; + + /** + * + * + * @generated + */ + private EClass eTreeEClass = null; + + /** + * Creates an instance of the model Package, registered with + * {@link org.eclipse.emf.ecore.EPackage.Registry EPackage.Registry} by the package + * package URI value. + *

                              Note: the correct way to create the package is via the static + * factory method {@link #init init()}, which also performs + * initialization of the package, or returns the registered package, + * if one already exists. + * + * + * @see org.eclipse.emf.ecore.EPackage.Registry + * @see com.ibm.wala.ecore.graph.GraphPackage#eNS_URI + * @see #init() + * @generated + */ + private GraphPackageImpl() { + super(eNS_URI, GraphFactory.eINSTANCE); + } + + /** + * + * + * @generated + */ + private static boolean isInited = false; + + /** + * Creates, registers, and initializes the Package for this + * model, and for any others upon which it depends. Simple + * dependencies are satisfied by calling this method on all + * dependent packages before doing anything else. This method drives + * initialization for interdependent packages directly, in parallel + * with this package, itself. + *

                              Of this package and its interdependencies, all packages which + * have not yet been registered by their URI values are first created + * and registered. The packages are then initialized in two steps: + * meta-model objects for all of the packages are created before any + * are initialized, since one package's meta-model objects may refer to + * those of another. + *

                              Invocation of this method will not affect any packages that have + * already been initialized. + * + * + * @see #eNS_URI + * @see #createPackageContents() + * @see #initializePackageContents() + * @generated + */ + public static GraphPackage init() { + if (isInited) return (GraphPackage)EPackage.Registry.INSTANCE.getEPackage(GraphPackage.eNS_URI); + + // Obtain or create and register package + GraphPackageImpl theGraphPackage = (GraphPackageImpl)(EPackage.Registry.INSTANCE.getEPackage(eNS_URI) instanceof GraphPackageImpl ? EPackage.Registry.INSTANCE.getEPackage(eNS_URI) : new GraphPackageImpl()); + + isInited = true; + + // Obtain or create and register interdependencies + CommonPackageImpl theCommonPackage = (CommonPackageImpl)(EPackage.Registry.INSTANCE.getEPackage(CommonPackage.eNS_URI) instanceof CommonPackageImpl ? EPackage.Registry.INSTANCE.getEPackage(CommonPackage.eNS_URI) : CommonPackage.eINSTANCE); + RegexPackageImpl theRegexPackage = (RegexPackageImpl)(EPackage.Registry.INSTANCE.getEPackage(RegexPackage.eNS_URI) instanceof RegexPackageImpl ? EPackage.Registry.INSTANCE.getEPackage(RegexPackage.eNS_URI) : RegexPackage.eINSTANCE); + PerfPackageImpl thePerfPackage = (PerfPackageImpl)(EPackage.Registry.INSTANCE.getEPackage(PerfPackage.eNS_URI) instanceof PerfPackageImpl ? EPackage.Registry.INSTANCE.getEPackage(PerfPackage.eNS_URI) : PerfPackage.eINSTANCE); + JavaPackageImpl theJavaPackage = (JavaPackageImpl)(EPackage.Registry.INSTANCE.getEPackage(JavaPackage.eNS_URI) instanceof JavaPackageImpl ? EPackage.Registry.INSTANCE.getEPackage(JavaPackage.eNS_URI) : JavaPackage.eINSTANCE); + CallGraphPackageImpl theCallGraphPackage = (CallGraphPackageImpl)(EPackage.Registry.INSTANCE.getEPackage(CallGraphPackage.eNS_URI) instanceof CallGraphPackageImpl ? EPackage.Registry.INSTANCE.getEPackage(CallGraphPackage.eNS_URI) : CallGraphPackage.eINSTANCE); + PointerAnalysisPackageImpl thePointerAnalysisPackage = (PointerAnalysisPackageImpl)(EPackage.Registry.INSTANCE.getEPackage(PointerAnalysisPackage.eNS_URI) instanceof PointerAnalysisPackageImpl ? EPackage.Registry.INSTANCE.getEPackage(PointerAnalysisPackage.eNS_URI) : PointerAnalysisPackage.eINSTANCE); + JavaScopePackageImpl theJavaScopePackage = (JavaScopePackageImpl)(EPackage.Registry.INSTANCE.getEPackage(JavaScopePackage.eNS_URI) instanceof JavaScopePackageImpl ? EPackage.Registry.INSTANCE.getEPackage(JavaScopePackage.eNS_URI) : JavaScopePackage.eINSTANCE); + J2EEScopePackageImpl theJ2EEScopePackage = (J2EEScopePackageImpl)(EPackage.Registry.INSTANCE.getEPackage(J2EEScopePackage.eNS_URI) instanceof J2EEScopePackageImpl ? EPackage.Registry.INSTANCE.getEPackage(J2EEScopePackage.eNS_URI) : J2EEScopePackage.eINSTANCE); + + // Create package meta-data objects + theGraphPackage.createPackageContents(); + theCommonPackage.createPackageContents(); + theRegexPackage.createPackageContents(); + thePerfPackage.createPackageContents(); + theJavaPackage.createPackageContents(); + theCallGraphPackage.createPackageContents(); + thePointerAnalysisPackage.createPackageContents(); + theJavaScopePackage.createPackageContents(); + theJ2EEScopePackage.createPackageContents(); + + // Initialize created meta-data + theGraphPackage.initializePackageContents(); + theCommonPackage.initializePackageContents(); + theRegexPackage.initializePackageContents(); + thePerfPackage.initializePackageContents(); + theJavaPackage.initializePackageContents(); + theCallGraphPackage.initializePackageContents(); + thePointerAnalysisPackage.initializePackageContents(); + theJavaScopePackage.initializePackageContents(); + theJ2EEScopePackage.initializePackageContents(); + + // Mark meta-data to indicate it can't be changed + theGraphPackage.freeze(); + + return theGraphPackage; + } + + /** + * + * + * @generated + */ + public EClass getEGraph() { + return eGraphEClass; + } + + /** + * + * + * @generated + */ + public EReference getEGraph_Nodes() { + return (EReference)eGraphEClass.getEStructuralFeatures().get(0); + } + + /** + * + * + * @generated + */ + public EReference getEGraph_Edges() { + return (EReference)eGraphEClass.getEStructuralFeatures().get(1); + } + + /** + * + * + * @generated + */ + public EClass getETree() { + return eTreeEClass; + } + + /** + * + * + * @generated + */ + public GraphFactory getGraphFactory() { + return (GraphFactory)getEFactoryInstance(); + } + + /** + * + * + * @generated + */ + private boolean isCreated = false; + + /** + * Creates the meta-model objects for the package. This method is + * guarded to have no affect on any invocation but its first. + * + * + * @generated + */ + public void createPackageContents() { + if (isCreated) return; + isCreated = true; + + // Create classes and their features + eGraphEClass = createEClass(EGRAPH); + createEReference(eGraphEClass, EGRAPH__NODES); + createEReference(eGraphEClass, EGRAPH__EDGES); + + eTreeEClass = createEClass(ETREE); + } + + /** + * + * + * @generated + */ + private boolean isInitialized = false; + + /** + * Complete the initialization of the package and its meta-model. This + * method is guarded to have no affect on any invocation but its first. + * + * + * @generated + */ + public void initializePackageContents() { + if (isInitialized) return; + isInitialized = true; + + // Initialize package + setName(eNAME); + setNsPrefix(eNS_PREFIX); + setNsURI(eNS_URI); + + // Obtain other dependent packages + CommonPackage theCommonPackage = (CommonPackage)EPackage.Registry.INSTANCE.getEPackage(CommonPackage.eNS_URI); + + // Add supertypes to classes + eTreeEClass.getESuperTypes().add(this.getEGraph()); + + // Initialize classes and features; add operations and parameters + initEClass(eGraphEClass, EGraph.class, "EGraph", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); + initEReference(getEGraph_Nodes(), theCommonPackage.getECollection(), null, "nodes", null, 1, 1, EGraph.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_COMPOSITE, IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); + initEReference(getEGraph_Edges(), theCommonPackage.getERelation(), null, "edges", null, 1, 1, EGraph.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, IS_COMPOSITE, !IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); + + initEClass(eTreeEClass, ETree.class, "ETree", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); + + // Create resource + createResource(eNS_URI); + } + +} //GraphPackageImpl diff --git a/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/graph/util/GraphAdapterFactory.java b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/graph/util/GraphAdapterFactory.java new file mode 100644 index 000000000..6ae04760c --- /dev/null +++ b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/graph/util/GraphAdapterFactory.java @@ -0,0 +1,137 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.graph.util; + +import com.ibm.wala.ecore.graph.*; + +import org.eclipse.emf.common.notify.Adapter; +import org.eclipse.emf.common.notify.Notifier; + +import org.eclipse.emf.common.notify.impl.AdapterFactoryImpl; + +import org.eclipse.emf.ecore.EObject; + +/** + * + * The Adapter Factory for the model. + * It provides an adapter createXXX method for each class of the model. + * + * @see com.ibm.wala.ecore.graph.GraphPackage + * @generated + */ +public class GraphAdapterFactory extends AdapterFactoryImpl { + /** + * The cached model package. + * + * + * @generated + */ + protected static GraphPackage modelPackage; + + /** + * Creates an instance of the adapter factory. + * + * + * @generated + */ + public GraphAdapterFactory() { + if (modelPackage == null) { + modelPackage = GraphPackage.eINSTANCE; + } + } + + /** + * Returns whether this factory is applicable for the type of the object. + * + * This implementation returns true if the object is either the model's package or is an instance object of the model. + * + * @return whether this factory is applicable for the type of the object. + * @generated + */ + public boolean isFactoryForType(Object object) { + if (object == modelPackage) { + return true; + } + if (object instanceof EObject) { + return ((EObject)object).eClass().getEPackage() == modelPackage; + } + return false; + } + + /** + * The switch the delegates to the createXXX methods. + * + * + * @generated + */ + protected GraphSwitch modelSwitch = + new GraphSwitch() { + public Object caseEGraph(EGraph object) { + return createEGraphAdapter(); + } + public Object caseETree(ETree object) { + return createETreeAdapter(); + } + public Object defaultCase(EObject object) { + return createEObjectAdapter(); + } + }; + + /** + * Creates an adapter for the target. + * + * + * @param target the object to adapt. + * @return the adapter for the target. + * @generated + */ + public Adapter createAdapter(Notifier target) { + return (Adapter)modelSwitch.doSwitch((EObject)target); + } + + + /** + * Creates a new adapter for an object of class '{@link com.ibm.wala.ecore.graph.EGraph EGraph}'. + * + * This default implementation returns null so that we can easily ignore cases; + * it's useful to ignore a case when inheritance will catch all the cases anyway. + * + * @return the new adapter. + * @see com.ibm.wala.ecore.graph.EGraph + * @generated + */ + public Adapter createEGraphAdapter() { + return null; + } + + /** + * Creates a new adapter for an object of class '{@link com.ibm.wala.ecore.graph.ETree ETree}'. + * + * This default implementation returns null so that we can easily ignore cases; + * it's useful to ignore a case when inheritance will catch all the cases anyway. + * + * @return the new adapter. + * @see com.ibm.wala.ecore.graph.ETree + * @generated + */ + public Adapter createETreeAdapter() { + return null; + } + + /** + * Creates a new adapter for the default case. + * + * This default implementation returns null. + * + * @return the new adapter. + * @generated + */ + public Adapter createEObjectAdapter() { + return null; + } + +} //GraphAdapterFactory diff --git a/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/graph/util/GraphSwitch.java b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/graph/util/GraphSwitch.java new file mode 100644 index 000000000..fc5ed43cc --- /dev/null +++ b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/graph/util/GraphSwitch.java @@ -0,0 +1,152 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.graph.util; + +import com.ibm.wala.ecore.graph.*; + +import java.util.List; + +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EObject; + +/** + * + * The Switch for the model's inheritance hierarchy. + * It supports the call {@link #doSwitch(EObject) doSwitch(object)} + * to invoke the caseXXX method for each class of the model, + * starting with the actual class of the object + * and proceeding up the inheritance hierarchy + * until a non-null result is returned, + * which is the result of the switch. + * + * @see com.ibm.wala.ecore.graph.GraphPackage + * @generated + */ +public class GraphSwitch { + /** + * The cached model package + * + * + * @generated + */ + protected static GraphPackage modelPackage; + + /** + * Creates an instance of the switch. + * + * + * @generated + */ + public GraphSwitch() { + if (modelPackage == null) { + modelPackage = GraphPackage.eINSTANCE; + } + } + + /** + * Calls caseXXX for each class of the model until one returns a non null result; it yields that result. + * + * + * @return the first non-null result returned by a caseXXX call. + * @generated + */ + public Object doSwitch(EObject theEObject) { + return doSwitch(theEObject.eClass(), theEObject); + } + + /** + * Calls caseXXX for each class of the model until one returns a non null result; it yields that result. + * + * + * @return the first non-null result returned by a caseXXX call. + * @generated + */ + protected Object doSwitch(EClass theEClass, EObject theEObject) { + if (theEClass.eContainer() == modelPackage) { + return doSwitch(theEClass.getClassifierID(), theEObject); + } + else { + List eSuperTypes = theEClass.getESuperTypes(); + return + eSuperTypes.isEmpty() ? + defaultCase(theEObject) : + doSwitch((EClass)eSuperTypes.get(0), theEObject); + } + } + + /** + * Calls caseXXX for each class of the model until one returns a non null result; it yields that result. + * + * + * @return the first non-null result returned by a caseXXX call. + * @generated + */ + protected Object doSwitch(int classifierID, EObject theEObject) { + switch (classifierID) { + case GraphPackage.EGRAPH: { + EGraph eGraph = (EGraph)theEObject; + Object result = caseEGraph(eGraph); + if (result == null) result = defaultCase(theEObject); + return result; + } + case GraphPackage.ETREE: { + ETree eTree = (ETree)theEObject; + Object result = caseETree(eTree); + if (result == null) result = caseEGraph(eTree); + if (result == null) result = defaultCase(theEObject); + return result; + } + default: return defaultCase(theEObject); + } + } + + /** + * Returns the result of interpretting the object as an instance of 'EGraph'. + * + * This implementation returns null; + * returning a non-null result will terminate the switch. + * + * @param object the target of the switch. + * @return the result of interpretting the object as an instance of 'EGraph'. + * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject) + * @generated + */ + public Object caseEGraph(EGraph object) { + return null; + } + + /** + * Returns the result of interpretting the object as an instance of 'ETree'. + * + * This implementation returns null; + * returning a non-null result will terminate the switch. + * + * @param object the target of the switch. + * @return the result of interpretting the object as an instance of 'ETree'. + * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject) + * @generated + */ + public Object caseETree(ETree object) { + return null; + } + + /** + * Returns the result of interpretting the object as an instance of 'EObject'. + * + * This implementation returns null; + * returning a non-null result will terminate the switch, but this is the last case anyway. + * + * @param object the target of the switch. + * @return the result of interpretting the object as an instance of 'EObject'. + * @see #doSwitch(org.eclipse.emf.ecore.EObject) + * @generated + */ + public Object defaultCase(EObject object) { + return null; + } + +} //GraphSwitch diff --git a/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/j2ee/scope/EEarFile.java b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/j2ee/scope/EEarFile.java new file mode 100644 index 000000000..d139d1886 --- /dev/null +++ b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/j2ee/scope/EEarFile.java @@ -0,0 +1,22 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.j2ee.scope; + +import com.ibm.wala.ecore.java.scope.EJarFile; + +/** + * + * A representation of the model object 'EEar File'. + * + * + * + * @see com.ibm.wala.ecore.j2ee.scope.J2EEScopePackage#getEEarFile() + * @model + * @generated + */ +public interface EEarFile extends EJarFile { +} // EEarFile \ No newline at end of file diff --git a/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/j2ee/scope/EJ2EEAnalysisScope.java b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/j2ee/scope/EJ2EEAnalysisScope.java new file mode 100644 index 000000000..e99cc38fb --- /dev/null +++ b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/j2ee/scope/EJ2EEAnalysisScope.java @@ -0,0 +1,22 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.j2ee.scope; + +import com.ibm.wala.ecore.java.scope.EJavaAnalysisScope; + +/** + * + * A representation of the model object 'EJ2EE Analysis Scope'. + * + * + * + * @see com.ibm.wala.ecore.j2ee.scope.J2EEScopePackage#getEJ2EEAnalysisScope() + * @model + * @generated + */ +public interface EJ2EEAnalysisScope extends EJavaAnalysisScope { +} // EJ2EEAnalysisScope \ No newline at end of file diff --git a/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/j2ee/scope/EWarFile.java b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/j2ee/scope/EWarFile.java new file mode 100644 index 000000000..6b5aef13d --- /dev/null +++ b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/j2ee/scope/EWarFile.java @@ -0,0 +1,22 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.j2ee.scope; + +import com.ibm.wala.ecore.java.scope.EJarFile; + +/** + * + * A representation of the model object 'EWar File'. + * + * + * + * @see com.ibm.wala.ecore.j2ee.scope.J2EEScopePackage#getEWarFile() + * @model + * @generated + */ +public interface EWarFile extends EJarFile { +} // EWarFile \ No newline at end of file diff --git a/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/j2ee/scope/J2EEScopeFactory.java b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/j2ee/scope/J2EEScopeFactory.java new file mode 100644 index 000000000..aebdf01fa --- /dev/null +++ b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/j2ee/scope/J2EEScopeFactory.java @@ -0,0 +1,64 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.j2ee.scope; + +import org.eclipse.emf.ecore.EFactory; + +/** + * + * The Factory for the model. + * It provides a create method for each non-abstract class of the model. + * + * @see com.ibm.wala.ecore.j2ee.scope.J2EEScopePackage + * @generated + */ +public interface J2EEScopeFactory extends EFactory { + /** + * The singleton instance of the factory. + * + * + * @generated + */ + J2EEScopeFactory eINSTANCE = com.ibm.wala.ecore.j2ee.scope.impl.J2EEScopeFactoryImpl.init(); + + /** + * Returns a new object of class 'EJ2EE Analysis Scope'. + * + * + * @return a new object of class 'EJ2EE Analysis Scope'. + * @generated + */ + EJ2EEAnalysisScope createEJ2EEAnalysisScope(); + + /** + * Returns a new object of class 'EEar File'. + * + * + * @return a new object of class 'EEar File'. + * @generated + */ + EEarFile createEEarFile(); + + /** + * Returns a new object of class 'EWar File'. + * + * + * @return a new object of class 'EWar File'. + * @generated + */ + EWarFile createEWarFile(); + + /** + * Returns the package supported by this factory. + * + * + * @return the package supported by this factory. + * @generated + */ + J2EEScopePackage getJ2EEScopePackage(); + +} //J2EEScopeFactory diff --git a/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/j2ee/scope/J2EEScopePackage.java b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/j2ee/scope/J2EEScopePackage.java new file mode 100644 index 000000000..9c356866e --- /dev/null +++ b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/j2ee/scope/J2EEScopePackage.java @@ -0,0 +1,240 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.j2ee.scope; + +import com.ibm.wala.ecore.java.scope.JavaScopePackage; + +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EPackage; + +/** + * + * The Package for the model. + * It contains accessors for the meta objects to represent + *

                                + *
                              • each class,
                              • + *
                              • each feature of each class,
                              • + *
                              • each enum,
                              • + *
                              • and each data type
                              • + *
                              + * + * @see com.ibm.wala.ecore.j2ee.scope.J2EEScopeFactory + * @model kind="package" + * @generated + */ +public interface J2EEScopePackage extends EPackage { + /** + * The package name. + * + * + * @generated + */ + String eNAME = "scope"; + + /** + * The package namespace URI. + * + * + * @generated + */ + String eNS_URI = "http:///com/ibm/wala/wala.ecore.j2ee.scope"; + + /** + * The package namespace name. + * + * + * @generated + */ + String eNS_PREFIX = "com.ibm.wala.j2ee.scope"; + + /** + * The singleton instance of the package. + * + * + * @generated + */ + J2EEScopePackage eINSTANCE = com.ibm.wala.ecore.j2ee.scope.impl.J2EEScopePackageImpl.init(); + + /** + * The meta object id for the '{@link com.ibm.wala.ecore.j2ee.scope.impl.EJ2EEAnalysisScopeImpl EJ2EE Analysis Scope}' class. + * + * + * @see com.ibm.wala.ecore.j2ee.scope.impl.EJ2EEAnalysisScopeImpl + * @see com.ibm.wala.ecore.j2ee.scope.impl.J2EEScopePackageImpl#getEJ2EEAnalysisScope() + * @generated + */ + int EJ2EE_ANALYSIS_SCOPE = 0; + + /** + * The feature id for the 'Loaders' containment reference list. + * + * + * @generated + * @ordered + */ + int EJ2EE_ANALYSIS_SCOPE__LOADERS = JavaScopePackage.EJAVA_ANALYSIS_SCOPE__LOADERS; + + /** + * The feature id for the 'Exclusion File Name' attribute. + * + * + * @generated + * @ordered + */ + int EJ2EE_ANALYSIS_SCOPE__EXCLUSION_FILE_NAME = JavaScopePackage.EJAVA_ANALYSIS_SCOPE__EXCLUSION_FILE_NAME; + + /** + * The number of structural features of the 'EJ2EE Analysis Scope' class. + * + * + * @generated + * @ordered + */ + int EJ2EE_ANALYSIS_SCOPE_FEATURE_COUNT = JavaScopePackage.EJAVA_ANALYSIS_SCOPE_FEATURE_COUNT + 0; + + /** + * The meta object id for the '{@link com.ibm.wala.ecore.j2ee.scope.impl.EEarFileImpl EEar File}' class. + * + * + * @see com.ibm.wala.ecore.j2ee.scope.impl.EEarFileImpl + * @see com.ibm.wala.ecore.j2ee.scope.impl.J2EEScopePackageImpl#getEEarFile() + * @generated + */ + int EEAR_FILE = 1; + + /** + * The feature id for the 'Url' attribute. + * + * + * @generated + * @ordered + */ + int EEAR_FILE__URL = JavaScopePackage.EJAR_FILE__URL; + + /** + * The number of structural features of the 'EEar File' class. + * + * + * @generated + * @ordered + */ + int EEAR_FILE_FEATURE_COUNT = JavaScopePackage.EJAR_FILE_FEATURE_COUNT + 0; + + /** + * The meta object id for the '{@link com.ibm.wala.ecore.j2ee.scope.impl.EWarFileImpl EWar File}' class. + * + * + * @see com.ibm.wala.ecore.j2ee.scope.impl.EWarFileImpl + * @see com.ibm.wala.ecore.j2ee.scope.impl.J2EEScopePackageImpl#getEWarFile() + * @generated + */ + int EWAR_FILE = 2; + + /** + * The feature id for the 'Url' attribute. + * + * + * @generated + * @ordered + */ + int EWAR_FILE__URL = JavaScopePackage.EJAR_FILE__URL; + + /** + * The number of structural features of the 'EWar File' class. + * + * + * @generated + * @ordered + */ + int EWAR_FILE_FEATURE_COUNT = JavaScopePackage.EJAR_FILE_FEATURE_COUNT + 0; + + + /** + * Returns the meta object for class '{@link com.ibm.wala.ecore.j2ee.scope.EJ2EEAnalysisScope EJ2EE Analysis Scope}'. + * + * + * @return the meta object for class 'EJ2EE Analysis Scope'. + * @see com.ibm.wala.ecore.j2ee.scope.EJ2EEAnalysisScope + * @generated + */ + EClass getEJ2EEAnalysisScope(); + + /** + * Returns the meta object for class '{@link com.ibm.wala.ecore.j2ee.scope.EEarFile EEar File}'. + * + * + * @return the meta object for class 'EEar File'. + * @see com.ibm.wala.ecore.j2ee.scope.EEarFile + * @generated + */ + EClass getEEarFile(); + + /** + * Returns the meta object for class '{@link com.ibm.wala.ecore.j2ee.scope.EWarFile EWar File}'. + * + * + * @return the meta object for class 'EWar File'. + * @see com.ibm.wala.ecore.j2ee.scope.EWarFile + * @generated + */ + EClass getEWarFile(); + + /** + * Returns the factory that creates the instances of the model. + * + * + * @return the factory that creates the instances of the model. + * @generated + */ + J2EEScopeFactory getJ2EEScopeFactory(); + + /** + * + * Defines literals for the meta objects that represent + *
                                + *
                              • each class,
                              • + *
                              • each feature of each class,
                              • + *
                              • each enum,
                              • + *
                              • and each data type
                              • + *
                              + * + * @generated + */ + interface Literals { + /** + * The meta object literal for the '{@link com.ibm.wala.ecore.j2ee.scope.impl.EJ2EEAnalysisScopeImpl EJ2EE Analysis Scope}' class. + * + * + * @see com.ibm.wala.ecore.j2ee.scope.impl.EJ2EEAnalysisScopeImpl + * @see com.ibm.wala.ecore.j2ee.scope.impl.J2EEScopePackageImpl#getEJ2EEAnalysisScope() + * @generated + */ + EClass EJ2EE_ANALYSIS_SCOPE = eINSTANCE.getEJ2EEAnalysisScope(); + + /** + * The meta object literal for the '{@link com.ibm.wala.ecore.j2ee.scope.impl.EEarFileImpl EEar File}' class. + * + * + * @see com.ibm.wala.ecore.j2ee.scope.impl.EEarFileImpl + * @see com.ibm.wala.ecore.j2ee.scope.impl.J2EEScopePackageImpl#getEEarFile() + * @generated + */ + EClass EEAR_FILE = eINSTANCE.getEEarFile(); + + /** + * The meta object literal for the '{@link com.ibm.wala.ecore.j2ee.scope.impl.EWarFileImpl EWar File}' class. + * + * + * @see com.ibm.wala.ecore.j2ee.scope.impl.EWarFileImpl + * @see com.ibm.wala.ecore.j2ee.scope.impl.J2EEScopePackageImpl#getEWarFile() + * @generated + */ + EClass EWAR_FILE = eINSTANCE.getEWarFile(); + + } + +} //J2EEScopePackage diff --git a/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/j2ee/scope/impl/EEarFileImpl.java b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/j2ee/scope/impl/EEarFileImpl.java new file mode 100644 index 000000000..f16ae8655 --- /dev/null +++ b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/j2ee/scope/impl/EEarFileImpl.java @@ -0,0 +1,44 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.j2ee.scope.impl; + +import com.ibm.wala.ecore.j2ee.scope.EEarFile; +import com.ibm.wala.ecore.j2ee.scope.J2EEScopePackage; + +import com.ibm.wala.ecore.java.scope.impl.EJarFileImpl; + +import org.eclipse.emf.ecore.EClass; + +/** + * + * An implementation of the model object 'EEar File'. + * + *

                              + *

                              + * + * @generated + */ +public class EEarFileImpl extends EJarFileImpl implements EEarFile { + /** + * + * + * @generated + */ + protected EEarFileImpl() { + super(); + } + + /** + * + * + * @generated + */ + protected EClass eStaticClass() { + return J2EEScopePackage.Literals.EEAR_FILE; + } + +} //EEarFileImpl \ No newline at end of file diff --git a/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/j2ee/scope/impl/EJ2EEAnalysisScopeImpl.java b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/j2ee/scope/impl/EJ2EEAnalysisScopeImpl.java new file mode 100644 index 000000000..cf7f1e21c --- /dev/null +++ b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/j2ee/scope/impl/EJ2EEAnalysisScopeImpl.java @@ -0,0 +1,44 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.j2ee.scope.impl; + +import com.ibm.wala.ecore.j2ee.scope.EJ2EEAnalysisScope; +import com.ibm.wala.ecore.j2ee.scope.J2EEScopePackage; + +import com.ibm.wala.ecore.java.scope.impl.EJavaAnalysisScopeImpl; + +import org.eclipse.emf.ecore.EClass; + +/** + * + * An implementation of the model object 'EJ2EE Analysis Scope'. + * + *

                              + *

                              + * + * @generated + */ +public class EJ2EEAnalysisScopeImpl extends EJavaAnalysisScopeImpl implements EJ2EEAnalysisScope { + /** + * + * + * @generated + */ + protected EJ2EEAnalysisScopeImpl() { + super(); + } + + /** + * + * + * @generated + */ + protected EClass eStaticClass() { + return J2EEScopePackage.Literals.EJ2EE_ANALYSIS_SCOPE; + } + +} //EJ2EEAnalysisScopeImpl \ No newline at end of file diff --git a/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/j2ee/scope/impl/EWarFileImpl.java b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/j2ee/scope/impl/EWarFileImpl.java new file mode 100644 index 000000000..306433631 --- /dev/null +++ b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/j2ee/scope/impl/EWarFileImpl.java @@ -0,0 +1,44 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.j2ee.scope.impl; + +import com.ibm.wala.ecore.j2ee.scope.EWarFile; +import com.ibm.wala.ecore.j2ee.scope.J2EEScopePackage; + +import com.ibm.wala.ecore.java.scope.impl.EJarFileImpl; + +import org.eclipse.emf.ecore.EClass; + +/** + * + * An implementation of the model object 'EWar File'. + * + *

                              + *

                              + * + * @generated + */ +public class EWarFileImpl extends EJarFileImpl implements EWarFile { + /** + * + * + * @generated + */ + protected EWarFileImpl() { + super(); + } + + /** + * + * + * @generated + */ + protected EClass eStaticClass() { + return J2EEScopePackage.Literals.EWAR_FILE; + } + +} //EWarFileImpl \ No newline at end of file diff --git a/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/j2ee/scope/impl/J2EEScopeFactoryImpl.java b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/j2ee/scope/impl/J2EEScopeFactoryImpl.java new file mode 100644 index 000000000..213e33f70 --- /dev/null +++ b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/j2ee/scope/impl/J2EEScopeFactoryImpl.java @@ -0,0 +1,119 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.j2ee.scope.impl; + +import com.ibm.wala.ecore.j2ee.scope.*; + +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EPackage; + +import org.eclipse.emf.ecore.impl.EFactoryImpl; + +import org.eclipse.emf.ecore.plugin.EcorePlugin; + +/** + * + * An implementation of the model Factory. + * + * @generated + */ +public class J2EEScopeFactoryImpl extends EFactoryImpl implements J2EEScopeFactory { + /** + * Creates the default factory implementation. + * + * + * @generated + */ + public static J2EEScopeFactory init() { + try { + J2EEScopeFactory theJ2EEScopeFactory = (J2EEScopeFactory)EPackage.Registry.INSTANCE.getEFactory("http:///com/ibm/wala/wala.ecore.j2ee.scope"); + if (theJ2EEScopeFactory != null) { + return theJ2EEScopeFactory; + } + } + catch (Exception exception) { + EcorePlugin.INSTANCE.log(exception); + } + return new J2EEScopeFactoryImpl(); + } + + /** + * Creates an instance of the factory. + * + * + * @generated + */ + public J2EEScopeFactoryImpl() { + super(); + } + + /** + * + * + * @generated + */ + public EObject create(EClass eClass) { + switch (eClass.getClassifierID()) { + case J2EEScopePackage.EJ2EE_ANALYSIS_SCOPE: return createEJ2EEAnalysisScope(); + case J2EEScopePackage.EEAR_FILE: return createEEarFile(); + case J2EEScopePackage.EWAR_FILE: return createEWarFile(); + default: + throw new IllegalArgumentException("The class '" + eClass.getName() + "' is not a valid classifier"); + } + } + + /** + * + * + * @generated + */ + public EJ2EEAnalysisScope createEJ2EEAnalysisScope() { + EJ2EEAnalysisScopeImpl ej2EEAnalysisScope = new EJ2EEAnalysisScopeImpl(); + return ej2EEAnalysisScope; + } + + /** + * + * + * @generated + */ + public EEarFile createEEarFile() { + EEarFileImpl eEarFile = new EEarFileImpl(); + return eEarFile; + } + + /** + * + * + * @generated + */ + public EWarFile createEWarFile() { + EWarFileImpl eWarFile = new EWarFileImpl(); + return eWarFile; + } + + /** + * + * + * @generated + */ + public J2EEScopePackage getJ2EEScopePackage() { + return (J2EEScopePackage)getEPackage(); + } + + /** + * + * + * @deprecated + * @generated + */ + public static J2EEScopePackage getPackage() { + return J2EEScopePackage.eINSTANCE; + } + +} //J2EEScopeFactoryImpl diff --git a/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/j2ee/scope/impl/J2EEScopePackageImpl.java b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/j2ee/scope/impl/J2EEScopePackageImpl.java new file mode 100644 index 000000000..d88ed1a7d --- /dev/null +++ b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/j2ee/scope/impl/J2EEScopePackageImpl.java @@ -0,0 +1,278 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.j2ee.scope.impl; + +import com.ibm.wala.ecore.common.CommonPackage; + +import com.ibm.wala.ecore.common.impl.CommonPackageImpl; + +import com.ibm.wala.ecore.graph.GraphPackage; + +import com.ibm.wala.ecore.graph.impl.GraphPackageImpl; + +import com.ibm.wala.ecore.j2ee.scope.EEarFile; +import com.ibm.wala.ecore.j2ee.scope.EJ2EEAnalysisScope; +import com.ibm.wala.ecore.j2ee.scope.EWarFile; +import com.ibm.wala.ecore.j2ee.scope.J2EEScopeFactory; +import com.ibm.wala.ecore.j2ee.scope.J2EEScopePackage; + +import com.ibm.wala.ecore.java.JavaPackage; + +import com.ibm.wala.ecore.java.callGraph.CallGraphPackage; + +import com.ibm.wala.ecore.java.callGraph.impl.CallGraphPackageImpl; + +import com.ibm.wala.ecore.java.impl.JavaPackageImpl; + +import com.ibm.wala.ecore.java.pointerAnalysis.PointerAnalysisPackage; + +import com.ibm.wala.ecore.java.pointerAnalysis.impl.PointerAnalysisPackageImpl; + +import com.ibm.wala.ecore.java.scope.JavaScopePackage; + +import com.ibm.wala.ecore.java.scope.impl.JavaScopePackageImpl; + +import com.ibm.wala.ecore.perf.PerfPackage; + +import com.ibm.wala.ecore.perf.impl.PerfPackageImpl; + +import com.ibm.wala.ecore.regex.RegexPackage; + +import com.ibm.wala.ecore.regex.impl.RegexPackageImpl; + +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EPackage; + +import org.eclipse.emf.ecore.impl.EPackageImpl; + +/** + * + * An implementation of the model Package. + * + * @generated + */ +public class J2EEScopePackageImpl extends EPackageImpl implements J2EEScopePackage { + /** + * + * + * @generated + */ + private EClass ej2EEAnalysisScopeEClass = null; + + /** + * + * + * @generated + */ + private EClass eEarFileEClass = null; + + /** + * + * + * @generated + */ + private EClass eWarFileEClass = null; + + /** + * Creates an instance of the model Package, registered with + * {@link org.eclipse.emf.ecore.EPackage.Registry EPackage.Registry} by the package + * package URI value. + *

                              Note: the correct way to create the package is via the static + * factory method {@link #init init()}, which also performs + * initialization of the package, or returns the registered package, + * if one already exists. + * + * + * @see org.eclipse.emf.ecore.EPackage.Registry + * @see com.ibm.wala.ecore.j2ee.scope.J2EEScopePackage#eNS_URI + * @see #init() + * @generated + */ + private J2EEScopePackageImpl() { + super(eNS_URI, J2EEScopeFactory.eINSTANCE); + } + + /** + * + * + * @generated + */ + private static boolean isInited = false; + + /** + * Creates, registers, and initializes the Package for this + * model, and for any others upon which it depends. Simple + * dependencies are satisfied by calling this method on all + * dependent packages before doing anything else. This method drives + * initialization for interdependent packages directly, in parallel + * with this package, itself. + *

                              Of this package and its interdependencies, all packages which + * have not yet been registered by their URI values are first created + * and registered. The packages are then initialized in two steps: + * meta-model objects for all of the packages are created before any + * are initialized, since one package's meta-model objects may refer to + * those of another. + *

                              Invocation of this method will not affect any packages that have + * already been initialized. + * + * + * @see #eNS_URI + * @see #createPackageContents() + * @see #initializePackageContents() + * @generated + */ + public static J2EEScopePackage init() { + if (isInited) return (J2EEScopePackage)EPackage.Registry.INSTANCE.getEPackage(J2EEScopePackage.eNS_URI); + + // Obtain or create and register package + J2EEScopePackageImpl theJ2EEScopePackage = (J2EEScopePackageImpl)(EPackage.Registry.INSTANCE.getEPackage(eNS_URI) instanceof J2EEScopePackageImpl ? EPackage.Registry.INSTANCE.getEPackage(eNS_URI) : new J2EEScopePackageImpl()); + + isInited = true; + + // Obtain or create and register interdependencies + GraphPackageImpl theGraphPackage = (GraphPackageImpl)(EPackage.Registry.INSTANCE.getEPackage(GraphPackage.eNS_URI) instanceof GraphPackageImpl ? EPackage.Registry.INSTANCE.getEPackage(GraphPackage.eNS_URI) : GraphPackage.eINSTANCE); + CommonPackageImpl theCommonPackage = (CommonPackageImpl)(EPackage.Registry.INSTANCE.getEPackage(CommonPackage.eNS_URI) instanceof CommonPackageImpl ? EPackage.Registry.INSTANCE.getEPackage(CommonPackage.eNS_URI) : CommonPackage.eINSTANCE); + RegexPackageImpl theRegexPackage = (RegexPackageImpl)(EPackage.Registry.INSTANCE.getEPackage(RegexPackage.eNS_URI) instanceof RegexPackageImpl ? EPackage.Registry.INSTANCE.getEPackage(RegexPackage.eNS_URI) : RegexPackage.eINSTANCE); + PerfPackageImpl thePerfPackage = (PerfPackageImpl)(EPackage.Registry.INSTANCE.getEPackage(PerfPackage.eNS_URI) instanceof PerfPackageImpl ? EPackage.Registry.INSTANCE.getEPackage(PerfPackage.eNS_URI) : PerfPackage.eINSTANCE); + JavaPackageImpl theJavaPackage = (JavaPackageImpl)(EPackage.Registry.INSTANCE.getEPackage(JavaPackage.eNS_URI) instanceof JavaPackageImpl ? EPackage.Registry.INSTANCE.getEPackage(JavaPackage.eNS_URI) : JavaPackage.eINSTANCE); + CallGraphPackageImpl theCallGraphPackage = (CallGraphPackageImpl)(EPackage.Registry.INSTANCE.getEPackage(CallGraphPackage.eNS_URI) instanceof CallGraphPackageImpl ? EPackage.Registry.INSTANCE.getEPackage(CallGraphPackage.eNS_URI) : CallGraphPackage.eINSTANCE); + PointerAnalysisPackageImpl thePointerAnalysisPackage = (PointerAnalysisPackageImpl)(EPackage.Registry.INSTANCE.getEPackage(PointerAnalysisPackage.eNS_URI) instanceof PointerAnalysisPackageImpl ? EPackage.Registry.INSTANCE.getEPackage(PointerAnalysisPackage.eNS_URI) : PointerAnalysisPackage.eINSTANCE); + JavaScopePackageImpl theJavaScopePackage = (JavaScopePackageImpl)(EPackage.Registry.INSTANCE.getEPackage(JavaScopePackage.eNS_URI) instanceof JavaScopePackageImpl ? EPackage.Registry.INSTANCE.getEPackage(JavaScopePackage.eNS_URI) : JavaScopePackage.eINSTANCE); + + // Create package meta-data objects + theJ2EEScopePackage.createPackageContents(); + theGraphPackage.createPackageContents(); + theCommonPackage.createPackageContents(); + theRegexPackage.createPackageContents(); + thePerfPackage.createPackageContents(); + theJavaPackage.createPackageContents(); + theCallGraphPackage.createPackageContents(); + thePointerAnalysisPackage.createPackageContents(); + theJavaScopePackage.createPackageContents(); + + // Initialize created meta-data + theJ2EEScopePackage.initializePackageContents(); + theGraphPackage.initializePackageContents(); + theCommonPackage.initializePackageContents(); + theRegexPackage.initializePackageContents(); + thePerfPackage.initializePackageContents(); + theJavaPackage.initializePackageContents(); + theCallGraphPackage.initializePackageContents(); + thePointerAnalysisPackage.initializePackageContents(); + theJavaScopePackage.initializePackageContents(); + + // Mark meta-data to indicate it can't be changed + theJ2EEScopePackage.freeze(); + + return theJ2EEScopePackage; + } + + /** + * + * + * @generated + */ + public EClass getEJ2EEAnalysisScope() { + return ej2EEAnalysisScopeEClass; + } + + /** + * + * + * @generated + */ + public EClass getEEarFile() { + return eEarFileEClass; + } + + /** + * + * + * @generated + */ + public EClass getEWarFile() { + return eWarFileEClass; + } + + /** + * + * + * @generated + */ + public J2EEScopeFactory getJ2EEScopeFactory() { + return (J2EEScopeFactory)getEFactoryInstance(); + } + + /** + * + * + * @generated + */ + private boolean isCreated = false; + + /** + * Creates the meta-model objects for the package. This method is + * guarded to have no affect on any invocation but its first. + * + * + * @generated + */ + public void createPackageContents() { + if (isCreated) return; + isCreated = true; + + // Create classes and their features + ej2EEAnalysisScopeEClass = createEClass(EJ2EE_ANALYSIS_SCOPE); + + eEarFileEClass = createEClass(EEAR_FILE); + + eWarFileEClass = createEClass(EWAR_FILE); + } + + /** + * + * + * @generated + */ + private boolean isInitialized = false; + + /** + * Complete the initialization of the package and its meta-model. This + * method is guarded to have no affect on any invocation but its first. + * + * + * @generated + */ + public void initializePackageContents() { + if (isInitialized) return; + isInitialized = true; + + // Initialize package + setName(eNAME); + setNsPrefix(eNS_PREFIX); + setNsURI(eNS_URI); + + // Obtain other dependent packages + JavaScopePackage theJavaScopePackage = (JavaScopePackage)EPackage.Registry.INSTANCE.getEPackage(JavaScopePackage.eNS_URI); + + // Add supertypes to classes + ej2EEAnalysisScopeEClass.getESuperTypes().add(theJavaScopePackage.getEJavaAnalysisScope()); + eEarFileEClass.getESuperTypes().add(theJavaScopePackage.getEJarFile()); + eWarFileEClass.getESuperTypes().add(theJavaScopePackage.getEJarFile()); + + // Initialize classes and features; add operations and parameters + initEClass(ej2EEAnalysisScopeEClass, EJ2EEAnalysisScope.class, "EJ2EEAnalysisScope", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); + + initEClass(eEarFileEClass, EEarFile.class, "EEarFile", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); + + initEClass(eWarFileEClass, EWarFile.class, "EWarFile", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); + + // Create resource + createResource(eNS_URI); + } + +} //J2EEScopePackageImpl diff --git a/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/j2ee/scope/util/J2EEScopeAdapterFactory.java b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/j2ee/scope/util/J2EEScopeAdapterFactory.java new file mode 100644 index 000000000..1f750aadd --- /dev/null +++ b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/j2ee/scope/util/J2EEScopeAdapterFactory.java @@ -0,0 +1,209 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.j2ee.scope.util; + +import com.ibm.wala.ecore.j2ee.scope.*; + +import com.ibm.wala.ecore.java.scope.EJarFile; +import com.ibm.wala.ecore.java.scope.EJavaAnalysisScope; +import com.ibm.wala.ecore.java.scope.EModule; + +import org.eclipse.emf.common.notify.Adapter; +import org.eclipse.emf.common.notify.Notifier; + +import org.eclipse.emf.common.notify.impl.AdapterFactoryImpl; + +import org.eclipse.emf.ecore.EObject; + +/** + * + * The Adapter Factory for the model. + * It provides an adapter createXXX method for each class of the model. + * + * @see com.ibm.wala.ecore.j2ee.scope.J2EEScopePackage + * @generated + */ +public class J2EEScopeAdapterFactory extends AdapterFactoryImpl { + /** + * The cached model package. + * + * + * @generated + */ + protected static J2EEScopePackage modelPackage; + + /** + * Creates an instance of the adapter factory. + * + * + * @generated + */ + public J2EEScopeAdapterFactory() { + if (modelPackage == null) { + modelPackage = J2EEScopePackage.eINSTANCE; + } + } + + /** + * Returns whether this factory is applicable for the type of the object. + * + * This implementation returns true if the object is either the model's package or is an instance object of the model. + * + * @return whether this factory is applicable for the type of the object. + * @generated + */ + public boolean isFactoryForType(Object object) { + if (object == modelPackage) { + return true; + } + if (object instanceof EObject) { + return ((EObject)object).eClass().getEPackage() == modelPackage; + } + return false; + } + + /** + * The switch the delegates to the createXXX methods. + * + * + * @generated + */ + protected J2EEScopeSwitch modelSwitch = + new J2EEScopeSwitch() { + public Object caseEJ2EEAnalysisScope(EJ2EEAnalysisScope object) { + return createEJ2EEAnalysisScopeAdapter(); + } + public Object caseEEarFile(EEarFile object) { + return createEEarFileAdapter(); + } + public Object caseEWarFile(EWarFile object) { + return createEWarFileAdapter(); + } + public Object caseEJavaAnalysisScope(EJavaAnalysisScope object) { + return createEJavaAnalysisScopeAdapter(); + } + public Object caseEModule(EModule object) { + return createEModuleAdapter(); + } + public Object caseEJarFile(EJarFile object) { + return createEJarFileAdapter(); + } + public Object defaultCase(EObject object) { + return createEObjectAdapter(); + } + }; + + /** + * Creates an adapter for the target. + * + * + * @param target the object to adapt. + * @return the adapter for the target. + * @generated + */ + public Adapter createAdapter(Notifier target) { + return (Adapter)modelSwitch.doSwitch((EObject)target); + } + + + /** + * Creates a new adapter for an object of class '{@link com.ibm.wala.ecore.j2ee.scope.EJ2EEAnalysisScope EJ2EE Analysis Scope}'. + * + * This default implementation returns null so that we can easily ignore cases; + * it's useful to ignore a case when inheritance will catch all the cases anyway. + * + * @return the new adapter. + * @see com.ibm.wala.ecore.j2ee.scope.EJ2EEAnalysisScope + * @generated + */ + public Adapter createEJ2EEAnalysisScopeAdapter() { + return null; + } + + /** + * Creates a new adapter for an object of class '{@link com.ibm.wala.ecore.j2ee.scope.EEarFile EEar File}'. + * + * This default implementation returns null so that we can easily ignore cases; + * it's useful to ignore a case when inheritance will catch all the cases anyway. + * + * @return the new adapter. + * @see com.ibm.wala.ecore.j2ee.scope.EEarFile + * @generated + */ + public Adapter createEEarFileAdapter() { + return null; + } + + /** + * Creates a new adapter for an object of class '{@link com.ibm.wala.ecore.j2ee.scope.EWarFile EWar File}'. + * + * This default implementation returns null so that we can easily ignore cases; + * it's useful to ignore a case when inheritance will catch all the cases anyway. + * + * @return the new adapter. + * @see com.ibm.wala.ecore.j2ee.scope.EWarFile + * @generated + */ + public Adapter createEWarFileAdapter() { + return null; + } + + /** + * Creates a new adapter for an object of class '{@link com.ibm.wala.ecore.java.scope.EJavaAnalysisScope EJava Analysis Scope}'. + * + * This default implementation returns null so that we can easily ignore cases; + * it's useful to ignore a case when inheritance will catch all the cases anyway. + * + * @return the new adapter. + * @see com.ibm.wala.ecore.java.scope.EJavaAnalysisScope + * @generated + */ + public Adapter createEJavaAnalysisScopeAdapter() { + return null; + } + + /** + * Creates a new adapter for an object of class '{@link com.ibm.wala.ecore.java.scope.EModule EModule}'. + * + * This default implementation returns null so that we can easily ignore cases; + * it's useful to ignore a case when inheritance will catch all the cases anyway. + * + * @return the new adapter. + * @see com.ibm.wala.ecore.java.scope.EModule + * @generated + */ + public Adapter createEModuleAdapter() { + return null; + } + + /** + * Creates a new adapter for an object of class '{@link com.ibm.wala.ecore.java.scope.EJarFile EJar File}'. + * + * This default implementation returns null so that we can easily ignore cases; + * it's useful to ignore a case when inheritance will catch all the cases anyway. + * + * @return the new adapter. + * @see com.ibm.wala.ecore.java.scope.EJarFile + * @generated + */ + public Adapter createEJarFileAdapter() { + return null; + } + + /** + * Creates a new adapter for the default case. + * + * This default implementation returns null. + * + * @return the new adapter. + * @generated + */ + public Adapter createEObjectAdapter() { + return null; + } + +} //J2EEScopeAdapterFactory diff --git a/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/j2ee/scope/util/J2EEScopeSwitch.java b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/j2ee/scope/util/J2EEScopeSwitch.java new file mode 100644 index 000000000..7877b9c37 --- /dev/null +++ b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/j2ee/scope/util/J2EEScopeSwitch.java @@ -0,0 +1,226 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.j2ee.scope.util; + +import com.ibm.wala.ecore.j2ee.scope.*; + +import com.ibm.wala.ecore.java.scope.EJarFile; +import com.ibm.wala.ecore.java.scope.EJavaAnalysisScope; +import com.ibm.wala.ecore.java.scope.EModule; + +import java.util.List; + +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EObject; + +/** + * + * The Switch for the model's inheritance hierarchy. + * It supports the call {@link #doSwitch(EObject) doSwitch(object)} + * to invoke the caseXXX method for each class of the model, + * starting with the actual class of the object + * and proceeding up the inheritance hierarchy + * until a non-null result is returned, + * which is the result of the switch. + * + * @see com.ibm.wala.ecore.j2ee.scope.J2EEScopePackage + * @generated + */ +public class J2EEScopeSwitch { + /** + * The cached model package + * + * + * @generated + */ + protected static J2EEScopePackage modelPackage; + + /** + * Creates an instance of the switch. + * + * + * @generated + */ + public J2EEScopeSwitch() { + if (modelPackage == null) { + modelPackage = J2EEScopePackage.eINSTANCE; + } + } + + /** + * Calls caseXXX for each class of the model until one returns a non null result; it yields that result. + * + * + * @return the first non-null result returned by a caseXXX call. + * @generated + */ + public Object doSwitch(EObject theEObject) { + return doSwitch(theEObject.eClass(), theEObject); + } + + /** + * Calls caseXXX for each class of the model until one returns a non null result; it yields that result. + * + * + * @return the first non-null result returned by a caseXXX call. + * @generated + */ + protected Object doSwitch(EClass theEClass, EObject theEObject) { + if (theEClass.eContainer() == modelPackage) { + return doSwitch(theEClass.getClassifierID(), theEObject); + } + else { + List eSuperTypes = theEClass.getESuperTypes(); + return + eSuperTypes.isEmpty() ? + defaultCase(theEObject) : + doSwitch((EClass)eSuperTypes.get(0), theEObject); + } + } + + /** + * Calls caseXXX for each class of the model until one returns a non null result; it yields that result. + * + * + * @return the first non-null result returned by a caseXXX call. + * @generated + */ + protected Object doSwitch(int classifierID, EObject theEObject) { + switch (classifierID) { + case J2EEScopePackage.EJ2EE_ANALYSIS_SCOPE: { + EJ2EEAnalysisScope ej2EEAnalysisScope = (EJ2EEAnalysisScope)theEObject; + Object result = caseEJ2EEAnalysisScope(ej2EEAnalysisScope); + if (result == null) result = caseEJavaAnalysisScope(ej2EEAnalysisScope); + if (result == null) result = defaultCase(theEObject); + return result; + } + case J2EEScopePackage.EEAR_FILE: { + EEarFile eEarFile = (EEarFile)theEObject; + Object result = caseEEarFile(eEarFile); + if (result == null) result = caseEJarFile(eEarFile); + if (result == null) result = caseEModule(eEarFile); + if (result == null) result = defaultCase(theEObject); + return result; + } + case J2EEScopePackage.EWAR_FILE: { + EWarFile eWarFile = (EWarFile)theEObject; + Object result = caseEWarFile(eWarFile); + if (result == null) result = caseEJarFile(eWarFile); + if (result == null) result = caseEModule(eWarFile); + if (result == null) result = defaultCase(theEObject); + return result; + } + default: return defaultCase(theEObject); + } + } + + /** + * Returns the result of interpretting the object as an instance of 'EJ2EE Analysis Scope'. + * + * This implementation returns null; + * returning a non-null result will terminate the switch. + * + * @param object the target of the switch. + * @return the result of interpretting the object as an instance of 'EJ2EE Analysis Scope'. + * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject) + * @generated + */ + public Object caseEJ2EEAnalysisScope(EJ2EEAnalysisScope object) { + return null; + } + + /** + * Returns the result of interpretting the object as an instance of 'EEar File'. + * + * This implementation returns null; + * returning a non-null result will terminate the switch. + * + * @param object the target of the switch. + * @return the result of interpretting the object as an instance of 'EEar File'. + * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject) + * @generated + */ + public Object caseEEarFile(EEarFile object) { + return null; + } + + /** + * Returns the result of interpretting the object as an instance of 'EWar File'. + * + * This implementation returns null; + * returning a non-null result will terminate the switch. + * + * @param object the target of the switch. + * @return the result of interpretting the object as an instance of 'EWar File'. + * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject) + * @generated + */ + public Object caseEWarFile(EWarFile object) { + return null; + } + + /** + * Returns the result of interpretting the object as an instance of 'EJava Analysis Scope'. + * + * This implementation returns null; + * returning a non-null result will terminate the switch. + * + * @param object the target of the switch. + * @return the result of interpretting the object as an instance of 'EJava Analysis Scope'. + * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject) + * @generated + */ + public Object caseEJavaAnalysisScope(EJavaAnalysisScope object) { + return null; + } + + /** + * Returns the result of interpretting the object as an instance of 'EModule'. + * + * This implementation returns null; + * returning a non-null result will terminate the switch. + * + * @param object the target of the switch. + * @return the result of interpretting the object as an instance of 'EModule'. + * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject) + * @generated + */ + public Object caseEModule(EModule object) { + return null; + } + + /** + * Returns the result of interpretting the object as an instance of 'EJar File'. + * + * This implementation returns null; + * returning a non-null result will terminate the switch. + * + * @param object the target of the switch. + * @return the result of interpretting the object as an instance of 'EJar File'. + * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject) + * @generated + */ + public Object caseEJarFile(EJarFile object) { + return null; + } + + /** + * Returns the result of interpretting the object as an instance of 'EObject'. + * + * This implementation returns null; + * returning a non-null result will terminate the switch, but this is the last case anyway. + * + * @param object the target of the switch. + * @return the result of interpretting the object as an instance of 'EObject'. + * @see #doSwitch(org.eclipse.emf.ecore.EObject) + * @generated + */ + public Object defaultCase(EObject object) { + return null; + } + +} //J2EEScopeSwitch diff --git a/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/ECallSite.java b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/ECallSite.java new file mode 100644 index 000000000..08404e30f --- /dev/null +++ b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/ECallSite.java @@ -0,0 +1,108 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java; + +import com.ibm.wala.ecore.common.EObjectWithContainerId; + +/** + * + * A representation of the model object 'ECall Site'. + * + * + *

                              + * The following features are supported: + *

                                + *
                              • {@link com.ibm.wala.ecore.java.ECallSite#getBytecodeIndex Bytecode Index}
                              • + *
                              • {@link com.ibm.wala.ecore.java.ECallSite#getJavaMethod Java Method}
                              • + *
                              • {@link com.ibm.wala.ecore.java.ECallSite#getDeclaredTarget Declared Target}
                              • + *
                              + *

                              + * + * @see com.ibm.wala.ecore.java.JavaPackage#getECallSite() + * @model + * @generated + */ +public interface ECallSite extends EObjectWithContainerId { + /** + * Returns the value of the 'Bytecode Index' attribute. + * + *

                              + * If the meaning of the 'Bytecode Index' attribute isn't clear, + * there really should be more of a description here... + *

                              + * + * @return the value of the 'Bytecode Index' attribute. + * @see #setBytecodeIndex(int) + * @see com.ibm.wala.ecore.java.JavaPackage#getECallSite_BytecodeIndex() + * @model + * @generated + */ + int getBytecodeIndex(); + + /** + * Sets the value of the '{@link com.ibm.wala.ecore.java.ECallSite#getBytecodeIndex Bytecode Index}' attribute. + * + * + * @param value the new value of the 'Bytecode Index' attribute. + * @see #getBytecodeIndex() + * @generated + */ + void setBytecodeIndex(int value); + + /** + * Returns the value of the 'Java Method' reference. + * + *

                              + * If the meaning of the 'Java Method' reference isn't clear, + * there really should be more of a description here... + *

                              + * + * @return the value of the 'Java Method' reference. + * @see #setJavaMethod(EJavaMethod) + * @see com.ibm.wala.ecore.java.JavaPackage#getECallSite_JavaMethod() + * @model required="true" + * @generated + */ + EJavaMethod getJavaMethod(); + + /** + * Sets the value of the '{@link com.ibm.wala.ecore.java.ECallSite#getJavaMethod Java Method}' reference. + * + * + * @param value the new value of the 'Java Method' reference. + * @see #getJavaMethod() + * @generated + */ + void setJavaMethod(EJavaMethod value); + + /** + * Returns the value of the 'Declared Target' reference. + * + *

                              + * If the meaning of the 'Declared Target' reference isn't clear, + * there really should be more of a description here... + *

                              + * + * @return the value of the 'Declared Target' reference. + * @see #setDeclaredTarget(EJavaMethod) + * @see com.ibm.wala.ecore.java.JavaPackage#getECallSite_DeclaredTarget() + * @model required="true" + * @generated + */ + EJavaMethod getDeclaredTarget(); + + /** + * Sets the value of the '{@link com.ibm.wala.ecore.java.ECallSite#getDeclaredTarget Declared Target}' reference. + * + * + * @param value the new value of the 'Declared Target' reference. + * @see #getDeclaredTarget() + * @generated + */ + void setDeclaredTarget(EJavaMethod value); + +} // ECallSite \ No newline at end of file diff --git a/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/EClassHierarchy.java b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/EClassHierarchy.java new file mode 100644 index 000000000..f1287fae6 --- /dev/null +++ b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/EClassHierarchy.java @@ -0,0 +1,22 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java; + +import com.ibm.wala.ecore.graph.ETree; + +/** + * + * A representation of the model object 'EClass Hierarchy'. + * + * + * + * @see com.ibm.wala.ecore.java.JavaPackage#getEClassHierarchy() + * @model + * @generated + */ +public interface EClassHierarchy extends ETree { +} // EClassHierarchy \ No newline at end of file diff --git a/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/EClassLoaderName.java b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/EClassLoaderName.java new file mode 100644 index 000000000..e92357df0 --- /dev/null +++ b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/EClassLoaderName.java @@ -0,0 +1,178 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import org.eclipse.emf.common.util.AbstractEnumerator; + +/** + * + * A representation of the literals of the enumeration 'EClass Loader Name', + * and utility methods for working with them. + * + * @see com.ibm.wala.ecore.java.JavaPackage#getEClassLoaderName() + * @model + * @generated + */ +public final class EClassLoaderName extends AbstractEnumerator { + /** + * The 'Application' literal value. + * + *

                              + * If the meaning of 'Application' literal object isn't clear, + * there really should be more of a description here... + *

                              + * + * @see #APPLICATION_LITERAL + * @model name="Application" + * @generated + * @ordered + */ + public static final int APPLICATION = 0; + + /** + * The 'Primordial' literal value. + * + *

                              + * If the meaning of 'Primordial' literal object isn't clear, + * there really should be more of a description here... + *

                              + * + * @see #PRIMORDIAL_LITERAL + * @model name="Primordial" + * @generated + * @ordered + */ + public static final int PRIMORDIAL = 1; + + /** + * The 'Extension' literal value. + * + *

                              + * If the meaning of 'Extension' literal object isn't clear, + * there really should be more of a description here... + *

                              + * + * @see #EXTENSION_LITERAL + * @model name="Extension" + * @generated + * @ordered + */ + public static final int EXTENSION = 2; + + /** + * The 'Application' literal object. + * + * + * @see #APPLICATION + * @generated + * @ordered + */ + public static final EClassLoaderName APPLICATION_LITERAL = new EClassLoaderName(APPLICATION, "Application", "Application"); + + /** + * The 'Primordial' literal object. + * + * + * @see #PRIMORDIAL + * @generated + * @ordered + */ + public static final EClassLoaderName PRIMORDIAL_LITERAL = new EClassLoaderName(PRIMORDIAL, "Primordial", "Primordial"); + + /** + * The 'Extension' literal object. + * + * + * @see #EXTENSION + * @generated + * @ordered + */ + public static final EClassLoaderName EXTENSION_LITERAL = new EClassLoaderName(EXTENSION, "Extension", "Extension"); + + /** + * An array of all the 'EClass Loader Name' enumerators. + * + * + * @generated + */ + private static final EClassLoaderName[] VALUES_ARRAY = + new EClassLoaderName[] { + APPLICATION_LITERAL, + PRIMORDIAL_LITERAL, + EXTENSION_LITERAL, + }; + + /** + * A public read-only list of all the 'EClass Loader Name' enumerators. + * + * + * @generated + */ + public static final List VALUES = Collections.unmodifiableList(Arrays.asList(VALUES_ARRAY)); + + /** + * Returns the 'EClass Loader Name' literal with the specified literal value. + * + * + * @generated + */ + public static EClassLoaderName get(String literal) { + for (int i = 0; i < VALUES_ARRAY.length; ++i) { + EClassLoaderName result = VALUES_ARRAY[i]; + if (result.toString().equals(literal)) { + return result; + } + } + return null; + } + + /** + * Returns the 'EClass Loader Name' literal with the specified name. + * + * + * @generated + */ + public static EClassLoaderName getByName(String name) { + for (int i = 0; i < VALUES_ARRAY.length; ++i) { + EClassLoaderName result = VALUES_ARRAY[i]; + if (result.getName().equals(name)) { + return result; + } + } + return null; + } + + /** + * Returns the 'EClass Loader Name' literal with the specified integer value. + * + * + * @generated + */ + public static EClassLoaderName get(int value) { + switch (value) { + case APPLICATION: return APPLICATION_LITERAL; + case PRIMORDIAL: return PRIMORDIAL_LITERAL; + case EXTENSION: return EXTENSION_LITERAL; + } + return null; + } + + /** + * Only this class can construct instances. + * + * + * @generated + */ + private EClassLoaderName(int value, String name, String literal) { + super(value, name, literal); + } + +} //EClassLoaderName diff --git a/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/EInterfaceHierarchy.java b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/EInterfaceHierarchy.java new file mode 100644 index 000000000..9ec5422e0 --- /dev/null +++ b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/EInterfaceHierarchy.java @@ -0,0 +1,22 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java; + +import com.ibm.wala.ecore.graph.EGraph; + +/** + * + * A representation of the model object 'EInterface Hierarchy'. + * + * + * + * @see com.ibm.wala.ecore.java.JavaPackage#getEInterfaceHierarchy() + * @model + * @generated + */ +public interface EInterfaceHierarchy extends EGraph { +} // EInterfaceHierarchy \ No newline at end of file diff --git a/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/EJavaClass.java b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/EJavaClass.java new file mode 100644 index 000000000..85271b0a2 --- /dev/null +++ b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/EJavaClass.java @@ -0,0 +1,84 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java; + +import com.ibm.wala.ecore.common.EObjectWithContainerId; + +/** + * + * A representation of the model object 'EJava Class'. + * + * + *

                              + * The following features are supported: + *

                                + *
                              • {@link com.ibm.wala.ecore.java.EJavaClass#getClassName Class Name}
                              • + *
                              • {@link com.ibm.wala.ecore.java.EJavaClass#getLoader Loader}
                              • + *
                              + *

                              + * + * @see com.ibm.wala.ecore.java.JavaPackage#getEJavaClass() + * @model + * @generated + */ +public interface EJavaClass extends EObjectWithContainerId { + /** + * Returns the value of the 'Class Name' attribute. + * + *

                              + * If the meaning of the 'Class Name' attribute isn't clear, + * there really should be more of a description here... + *

                              + * + * @return the value of the 'Class Name' attribute. + * @see #setClassName(String) + * @see com.ibm.wala.ecore.java.JavaPackage#getEJavaClass_ClassName() + * @model required="true" + * @generated + */ + String getClassName(); + + /** + * Sets the value of the '{@link com.ibm.wala.ecore.java.EJavaClass#getClassName Class Name}' attribute. + * + * + * @param value the new value of the 'Class Name' attribute. + * @see #getClassName() + * @generated + */ + void setClassName(String value); + + /** + * Returns the value of the 'Loader' attribute. + * The literals are from the enumeration {@link com.ibm.wala.ecore.java.EClassLoaderName}. + * + *

                              + * If the meaning of the 'Loader' attribute isn't clear, + * there really should be more of a description here... + *

                              + * + * @return the value of the 'Loader' attribute. + * @see com.ibm.wala.ecore.java.EClassLoaderName + * @see #setLoader(EClassLoaderName) + * @see com.ibm.wala.ecore.java.JavaPackage#getEJavaClass_Loader() + * @model required="true" + * @generated + */ + EClassLoaderName getLoader(); + + /** + * Sets the value of the '{@link com.ibm.wala.ecore.java.EJavaClass#getLoader Loader}' attribute. + * + * + * @param value the new value of the 'Loader' attribute. + * @see com.ibm.wala.ecore.java.EClassLoaderName + * @see #getLoader() + * @generated + */ + void setLoader(EClassLoaderName value); + +} // EJavaClass \ No newline at end of file diff --git a/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/EJavaMethod.java b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/EJavaMethod.java new file mode 100644 index 000000000..1ba78d46b --- /dev/null +++ b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/EJavaMethod.java @@ -0,0 +1,132 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java; + +import com.ibm.wala.ecore.common.EObjectWithContainerId; + +/** + * + * A representation of the model object 'EJava Method'. + * + * + *

                              + * The following features are supported: + *

                                + *
                              • {@link com.ibm.wala.ecore.java.EJavaMethod#getMethodName Method Name}
                              • + *
                              • {@link com.ibm.wala.ecore.java.EJavaMethod#getDescriptor Descriptor}
                              • + *
                              • {@link com.ibm.wala.ecore.java.EJavaMethod#getJavaClass Java Class}
                              • + *
                              • {@link com.ibm.wala.ecore.java.EJavaMethod#getSignature Signature}
                              • + *
                              + *

                              + * + * @see com.ibm.wala.ecore.java.JavaPackage#getEJavaMethod() + * @model + * @generated + */ +public interface EJavaMethod extends EObjectWithContainerId { + /** + * Returns the value of the 'Method Name' attribute. + * + *

                              + * If the meaning of the 'Method Name' attribute isn't clear, + * there really should be more of a description here... + *

                              + * + * @return the value of the 'Method Name' attribute. + * @see #setMethodName(String) + * @see com.ibm.wala.ecore.java.JavaPackage#getEJavaMethod_MethodName() + * @model required="true" + * @generated + */ + String getMethodName(); + + /** + * Sets the value of the '{@link com.ibm.wala.ecore.java.EJavaMethod#getMethodName Method Name}' attribute. + * + * + * @param value the new value of the 'Method Name' attribute. + * @see #getMethodName() + * @generated + */ + void setMethodName(String value); + + /** + * Returns the value of the 'Descriptor' attribute. + * + *

                              + * If the meaning of the 'Descriptor' attribute isn't clear, + * there really should be more of a description here... + *

                              + * + * @return the value of the 'Descriptor' attribute. + * @see #setDescriptor(String) + * @see com.ibm.wala.ecore.java.JavaPackage#getEJavaMethod_Descriptor() + * @model required="true" + * @generated + */ + String getDescriptor(); + + /** + * Sets the value of the '{@link com.ibm.wala.ecore.java.EJavaMethod#getDescriptor Descriptor}' attribute. + * + * + * @param value the new value of the 'Descriptor' attribute. + * @see #getDescriptor() + * @generated + */ + void setDescriptor(String value); + + /** + * Returns the value of the 'Java Class' reference. + * + *

                              + * If the meaning of the 'Java Class' reference isn't clear, + * there really should be more of a description here... + *

                              + * + * @return the value of the 'Java Class' reference. + * @see #setJavaClass(EJavaClass) + * @see com.ibm.wala.ecore.java.JavaPackage#getEJavaMethod_JavaClass() + * @model required="true" + * @generated + */ + EJavaClass getJavaClass(); + + /** + * Sets the value of the '{@link com.ibm.wala.ecore.java.EJavaMethod#getJavaClass Java Class}' reference. + * + * + * @param value the new value of the 'Java Class' reference. + * @see #getJavaClass() + * @generated + */ + void setJavaClass(EJavaClass value); + + /** + * Returns the value of the 'Signature' attribute. + * + *

                              + * If the meaning of the 'Signature' attribute isn't clear, + * there really should be more of a description here... + *

                              + * + * @return the value of the 'Signature' attribute. + * @see com.ibm.wala.ecore.java.JavaPackage#getEJavaMethod_Signature() + * @model transient="true" changeable="false" volatile="true" derived="true" + * @generated + */ + String getSignature(); + + /** + * + * + * @model kind="operation" ordered="false" + * @generated + */ + boolean isClinit(); + +} // EJavaMethod \ No newline at end of file diff --git a/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/ETypeHierarchy.java b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/ETypeHierarchy.java new file mode 100644 index 000000000..bf29884af --- /dev/null +++ b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/ETypeHierarchy.java @@ -0,0 +1,110 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java; + +import com.ibm.wala.ecore.common.ERelation; + +import org.eclipse.emf.ecore.EObject; + +/** + * + * A representation of the model object 'EType Hierarchy'. + * + * + *

                              + * The following features are supported: + *

                                + *
                              • {@link com.ibm.wala.ecore.java.ETypeHierarchy#getClasses Classes}
                              • + *
                              • {@link com.ibm.wala.ecore.java.ETypeHierarchy#getInterfaces Interfaces}
                              • + *
                              • {@link com.ibm.wala.ecore.java.ETypeHierarchy#getImplements Implements}
                              • + *
                              + *

                              + * + * @see com.ibm.wala.ecore.java.JavaPackage#getETypeHierarchy() + * @model + * @generated + */ +public interface ETypeHierarchy extends EObject { + /** + * Returns the value of the 'Classes' containment reference. + * + *

                              + * If the meaning of the 'Classes' containment reference isn't clear, + * there really should be more of a description here... + *

                              + * + * @return the value of the 'Classes' containment reference. + * @see #setClasses(EClassHierarchy) + * @see com.ibm.wala.ecore.java.JavaPackage#getETypeHierarchy_Classes() + * @model containment="true" required="true" + * @generated + */ + EClassHierarchy getClasses(); + + /** + * Sets the value of the '{@link com.ibm.wala.ecore.java.ETypeHierarchy#getClasses Classes}' containment reference. + * + * + * @param value the new value of the 'Classes' containment reference. + * @see #getClasses() + * @generated + */ + void setClasses(EClassHierarchy value); + + /** + * Returns the value of the 'Interfaces' containment reference. + * + *

                              + * If the meaning of the 'Interfaces' containment reference isn't clear, + * there really should be more of a description here... + *

                              + * + * @return the value of the 'Interfaces' containment reference. + * @see #setInterfaces(EInterfaceHierarchy) + * @see com.ibm.wala.ecore.java.JavaPackage#getETypeHierarchy_Interfaces() + * @model containment="true" required="true" + * @generated + */ + EInterfaceHierarchy getInterfaces(); + + /** + * Sets the value of the '{@link com.ibm.wala.ecore.java.ETypeHierarchy#getInterfaces Interfaces}' containment reference. + * + * + * @param value the new value of the 'Interfaces' containment reference. + * @see #getInterfaces() + * @generated + */ + void setInterfaces(EInterfaceHierarchy value); + + /** + * Returns the value of the 'Implements' containment reference. + * + *

                              + * If the meaning of the 'Implements' containment reference isn't clear, + * there really should be more of a description here... + *

                              + * + * @return the value of the 'Implements' containment reference. + * @see #setImplements(ERelation) + * @see com.ibm.wala.ecore.java.JavaPackage#getETypeHierarchy_Implements() + * @model containment="true" required="true" + * @generated + */ + ERelation getImplements(); + + /** + * Sets the value of the '{@link com.ibm.wala.ecore.java.ETypeHierarchy#getImplements Implements}' containment reference. + * + * + * @param value the new value of the 'Implements' containment reference. + * @see #getImplements() + * @generated + */ + void setImplements(ERelation value); + +} // ETypeHierarchy \ No newline at end of file diff --git a/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/JavaFactory.java b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/JavaFactory.java new file mode 100644 index 000000000..08c88d4a0 --- /dev/null +++ b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/JavaFactory.java @@ -0,0 +1,91 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java; + +import org.eclipse.emf.ecore.EFactory; + +/** + * + * The Factory for the model. + * It provides a create method for each non-abstract class of the model. + * + * @see com.ibm.wala.ecore.java.JavaPackage + * @generated + */ +public interface JavaFactory extends EFactory { + /** + * The singleton instance of the factory. + * + * + * @generated + */ + JavaFactory eINSTANCE = com.ibm.wala.ecore.java.impl.JavaFactoryImpl.init(); + + /** + * Returns a new object of class 'EJava Class'. + * + * + * @return a new object of class 'EJava Class'. + * @generated + */ + EJavaClass createEJavaClass(); + + /** + * Returns a new object of class 'EJava Method'. + * + * + * @return a new object of class 'EJava Method'. + * @generated + */ + EJavaMethod createEJavaMethod(); + + /** + * Returns a new object of class 'ECall Site'. + * + * + * @return a new object of class 'ECall Site'. + * @generated + */ + ECallSite createECallSite(); + + /** + * Returns a new object of class 'EClass Hierarchy'. + * + * + * @return a new object of class 'EClass Hierarchy'. + * @generated + */ + EClassHierarchy createEClassHierarchy(); + + /** + * Returns a new object of class 'EInterface Hierarchy'. + * + * + * @return a new object of class 'EInterface Hierarchy'. + * @generated + */ + EInterfaceHierarchy createEInterfaceHierarchy(); + + /** + * Returns a new object of class 'EType Hierarchy'. + * + * + * @return a new object of class 'EType Hierarchy'. + * @generated + */ + ETypeHierarchy createETypeHierarchy(); + + /** + * Returns the package supported by this factory. + * + * + * @return the package supported by this factory. + * @generated + */ + JavaPackage getJavaPackage(); + +} //JavaFactory diff --git a/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/JavaPackage.java b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/JavaPackage.java new file mode 100644 index 000000000..f12585aec --- /dev/null +++ b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/JavaPackage.java @@ -0,0 +1,755 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java; + +import com.ibm.wala.ecore.common.CommonPackage; + +import com.ibm.wala.ecore.graph.GraphPackage; + +import org.eclipse.emf.ecore.EAttribute; +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EEnum; +import org.eclipse.emf.ecore.EPackage; +import org.eclipse.emf.ecore.EReference; + +/** + * + * The Package for the model. + * It contains accessors for the meta objects to represent + *
                                + *
                              • each class,
                              • + *
                              • each feature of each class,
                              • + *
                              • each enum,
                              • + *
                              • and each data type
                              • + *
                              + * + * @see com.ibm.wala.ecore.java.JavaFactory + * @model kind="package" + * @generated + */ +public interface JavaPackage extends EPackage { + /** + * The package name. + * + * + * @generated + */ + String eNAME = "java"; + + /** + * The package namespace URI. + * + * + * @generated + */ + String eNS_URI = "http:///com/ibm/wala/wala.ecore.java"; + + /** + * The package namespace name. + * + * + * @generated + */ + String eNS_PREFIX = "com.ibm.wala.java"; + + /** + * The singleton instance of the package. + * + * + * @generated + */ + JavaPackage eINSTANCE = com.ibm.wala.ecore.java.impl.JavaPackageImpl.init(); + + /** + * The meta object id for the '{@link com.ibm.wala.ecore.java.impl.EJavaClassImpl EJava Class}' class. + * + * + * @see com.ibm.wala.ecore.java.impl.EJavaClassImpl + * @see com.ibm.wala.ecore.java.impl.JavaPackageImpl#getEJavaClass() + * @generated + */ + int EJAVA_CLASS = 0; + + /** + * The feature id for the 'Id' attribute. + * + * + * @generated + * @ordered + */ + int EJAVA_CLASS__ID = CommonPackage.EOBJECT_WITH_CONTAINER_ID__ID; + + /** + * The feature id for the 'Class Name' attribute. + * + * + * @generated + * @ordered + */ + int EJAVA_CLASS__CLASS_NAME = CommonPackage.EOBJECT_WITH_CONTAINER_ID_FEATURE_COUNT + 0; + + /** + * The feature id for the 'Loader' attribute. + * + * + * @generated + * @ordered + */ + int EJAVA_CLASS__LOADER = CommonPackage.EOBJECT_WITH_CONTAINER_ID_FEATURE_COUNT + 1; + + /** + * The number of structural features of the 'EJava Class' class. + * + * + * @generated + * @ordered + */ + int EJAVA_CLASS_FEATURE_COUNT = CommonPackage.EOBJECT_WITH_CONTAINER_ID_FEATURE_COUNT + 2; + + /** + * The meta object id for the '{@link com.ibm.wala.ecore.java.impl.EJavaMethodImpl EJava Method}' class. + * + * + * @see com.ibm.wala.ecore.java.impl.EJavaMethodImpl + * @see com.ibm.wala.ecore.java.impl.JavaPackageImpl#getEJavaMethod() + * @generated + */ + int EJAVA_METHOD = 1; + + /** + * The feature id for the 'Id' attribute. + * + * + * @generated + * @ordered + */ + int EJAVA_METHOD__ID = CommonPackage.EOBJECT_WITH_CONTAINER_ID__ID; + + /** + * The feature id for the 'Method Name' attribute. + * + * + * @generated + * @ordered + */ + int EJAVA_METHOD__METHOD_NAME = CommonPackage.EOBJECT_WITH_CONTAINER_ID_FEATURE_COUNT + 0; + + /** + * The feature id for the 'Descriptor' attribute. + * + * + * @generated + * @ordered + */ + int EJAVA_METHOD__DESCRIPTOR = CommonPackage.EOBJECT_WITH_CONTAINER_ID_FEATURE_COUNT + 1; + + /** + * The feature id for the 'Java Class' reference. + * + * + * @generated + * @ordered + */ + int EJAVA_METHOD__JAVA_CLASS = CommonPackage.EOBJECT_WITH_CONTAINER_ID_FEATURE_COUNT + 2; + + /** + * The feature id for the 'Signature' attribute. + * + * + * @generated + * @ordered + */ + int EJAVA_METHOD__SIGNATURE = CommonPackage.EOBJECT_WITH_CONTAINER_ID_FEATURE_COUNT + 3; + + /** + * The number of structural features of the 'EJava Method' class. + * + * + * @generated + * @ordered + */ + int EJAVA_METHOD_FEATURE_COUNT = CommonPackage.EOBJECT_WITH_CONTAINER_ID_FEATURE_COUNT + 4; + + /** + * The meta object id for the '{@link com.ibm.wala.ecore.java.impl.ECallSiteImpl ECall Site}' class. + * + * + * @see com.ibm.wala.ecore.java.impl.ECallSiteImpl + * @see com.ibm.wala.ecore.java.impl.JavaPackageImpl#getECallSite() + * @generated + */ + int ECALL_SITE = 2; + + /** + * The feature id for the 'Id' attribute. + * + * + * @generated + * @ordered + */ + int ECALL_SITE__ID = CommonPackage.EOBJECT_WITH_CONTAINER_ID__ID; + + /** + * The feature id for the 'Bytecode Index' attribute. + * + * + * @generated + * @ordered + */ + int ECALL_SITE__BYTECODE_INDEX = CommonPackage.EOBJECT_WITH_CONTAINER_ID_FEATURE_COUNT + 0; + + /** + * The feature id for the 'Java Method' reference. + * + * + * @generated + * @ordered + */ + int ECALL_SITE__JAVA_METHOD = CommonPackage.EOBJECT_WITH_CONTAINER_ID_FEATURE_COUNT + 1; + + /** + * The feature id for the 'Declared Target' reference. + * + * + * @generated + * @ordered + */ + int ECALL_SITE__DECLARED_TARGET = CommonPackage.EOBJECT_WITH_CONTAINER_ID_FEATURE_COUNT + 2; + + /** + * The number of structural features of the 'ECall Site' class. + * + * + * @generated + * @ordered + */ + int ECALL_SITE_FEATURE_COUNT = CommonPackage.EOBJECT_WITH_CONTAINER_ID_FEATURE_COUNT + 3; + + /** + * The meta object id for the '{@link com.ibm.wala.ecore.java.impl.EClassHierarchyImpl EClass Hierarchy}' class. + * + * + * @see com.ibm.wala.ecore.java.impl.EClassHierarchyImpl + * @see com.ibm.wala.ecore.java.impl.JavaPackageImpl#getEClassHierarchy() + * @generated + */ + int ECLASS_HIERARCHY = 3; + + /** + * The feature id for the 'Nodes' reference. + * + * + * @generated + * @ordered + */ + int ECLASS_HIERARCHY__NODES = GraphPackage.ETREE__NODES; + + /** + * The feature id for the 'Edges' containment reference. + * + * + * @generated + * @ordered + */ + int ECLASS_HIERARCHY__EDGES = GraphPackage.ETREE__EDGES; + + /** + * The number of structural features of the 'EClass Hierarchy' class. + * + * + * @generated + * @ordered + */ + int ECLASS_HIERARCHY_FEATURE_COUNT = GraphPackage.ETREE_FEATURE_COUNT + 0; + + /** + * The meta object id for the '{@link com.ibm.wala.ecore.java.impl.EInterfaceHierarchyImpl EInterface Hierarchy}' class. + * + * + * @see com.ibm.wala.ecore.java.impl.EInterfaceHierarchyImpl + * @see com.ibm.wala.ecore.java.impl.JavaPackageImpl#getEInterfaceHierarchy() + * @generated + */ + int EINTERFACE_HIERARCHY = 4; + + /** + * The feature id for the 'Nodes' reference. + * + * + * @generated + * @ordered + */ + int EINTERFACE_HIERARCHY__NODES = GraphPackage.EGRAPH__NODES; + + /** + * The feature id for the 'Edges' containment reference. + * + * + * @generated + * @ordered + */ + int EINTERFACE_HIERARCHY__EDGES = GraphPackage.EGRAPH__EDGES; + + /** + * The number of structural features of the 'EInterface Hierarchy' class. + * + * + * @generated + * @ordered + */ + int EINTERFACE_HIERARCHY_FEATURE_COUNT = GraphPackage.EGRAPH_FEATURE_COUNT + 0; + + /** + * The meta object id for the '{@link com.ibm.wala.ecore.java.impl.ETypeHierarchyImpl EType Hierarchy}' class. + * + * + * @see com.ibm.wala.ecore.java.impl.ETypeHierarchyImpl + * @see com.ibm.wala.ecore.java.impl.JavaPackageImpl#getETypeHierarchy() + * @generated + */ + int ETYPE_HIERARCHY = 5; + + /** + * The feature id for the 'Classes' containment reference. + * + * + * @generated + * @ordered + */ + int ETYPE_HIERARCHY__CLASSES = 0; + + /** + * The feature id for the 'Interfaces' containment reference. + * + * + * @generated + * @ordered + */ + int ETYPE_HIERARCHY__INTERFACES = 1; + + /** + * The feature id for the 'Implements' containment reference. + * + * + * @generated + * @ordered + */ + int ETYPE_HIERARCHY__IMPLEMENTS = 2; + + /** + * The number of structural features of the 'EType Hierarchy' class. + * + * + * @generated + * @ordered + */ + int ETYPE_HIERARCHY_FEATURE_COUNT = 3; + + /** + * The meta object id for the '{@link com.ibm.wala.ecore.java.EClassLoaderName EClass Loader Name}' enum. + * + * + * @see com.ibm.wala.ecore.java.EClassLoaderName + * @see com.ibm.wala.ecore.java.impl.JavaPackageImpl#getEClassLoaderName() + * @generated + */ + int ECLASS_LOADER_NAME = 6; + + + /** + * Returns the meta object for class '{@link com.ibm.wala.ecore.java.EJavaClass EJava Class}'. + * + * + * @return the meta object for class 'EJava Class'. + * @see com.ibm.wala.ecore.java.EJavaClass + * @generated + */ + EClass getEJavaClass(); + + /** + * Returns the meta object for the attribute '{@link com.ibm.wala.ecore.java.EJavaClass#getClassName Class Name}'. + * + * + * @return the meta object for the attribute 'Class Name'. + * @see com.ibm.wala.ecore.java.EJavaClass#getClassName() + * @see #getEJavaClass() + * @generated + */ + EAttribute getEJavaClass_ClassName(); + + /** + * Returns the meta object for the attribute '{@link com.ibm.wala.ecore.java.EJavaClass#getLoader Loader}'. + * + * + * @return the meta object for the attribute 'Loader'. + * @see com.ibm.wala.ecore.java.EJavaClass#getLoader() + * @see #getEJavaClass() + * @generated + */ + EAttribute getEJavaClass_Loader(); + + /** + * Returns the meta object for class '{@link com.ibm.wala.ecore.java.EJavaMethod EJava Method}'. + * + * + * @return the meta object for class 'EJava Method'. + * @see com.ibm.wala.ecore.java.EJavaMethod + * @generated + */ + EClass getEJavaMethod(); + + /** + * Returns the meta object for the attribute '{@link com.ibm.wala.ecore.java.EJavaMethod#getMethodName Method Name}'. + * + * + * @return the meta object for the attribute 'Method Name'. + * @see com.ibm.wala.ecore.java.EJavaMethod#getMethodName() + * @see #getEJavaMethod() + * @generated + */ + EAttribute getEJavaMethod_MethodName(); + + /** + * Returns the meta object for the attribute '{@link com.ibm.wala.ecore.java.EJavaMethod#getDescriptor Descriptor}'. + * + * + * @return the meta object for the attribute 'Descriptor'. + * @see com.ibm.wala.ecore.java.EJavaMethod#getDescriptor() + * @see #getEJavaMethod() + * @generated + */ + EAttribute getEJavaMethod_Descriptor(); + + /** + * Returns the meta object for the reference '{@link com.ibm.wala.ecore.java.EJavaMethod#getJavaClass Java Class}'. + * + * + * @return the meta object for the reference 'Java Class'. + * @see com.ibm.wala.ecore.java.EJavaMethod#getJavaClass() + * @see #getEJavaMethod() + * @generated + */ + EReference getEJavaMethod_JavaClass(); + + /** + * Returns the meta object for the attribute '{@link com.ibm.wala.ecore.java.EJavaMethod#getSignature Signature}'. + * + * + * @return the meta object for the attribute 'Signature'. + * @see com.ibm.wala.ecore.java.EJavaMethod#getSignature() + * @see #getEJavaMethod() + * @generated + */ + EAttribute getEJavaMethod_Signature(); + + /** + * Returns the meta object for class '{@link com.ibm.wala.ecore.java.ECallSite ECall Site}'. + * + * + * @return the meta object for class 'ECall Site'. + * @see com.ibm.wala.ecore.java.ECallSite + * @generated + */ + EClass getECallSite(); + + /** + * Returns the meta object for the attribute '{@link com.ibm.wala.ecore.java.ECallSite#getBytecodeIndex Bytecode Index}'. + * + * + * @return the meta object for the attribute 'Bytecode Index'. + * @see com.ibm.wala.ecore.java.ECallSite#getBytecodeIndex() + * @see #getECallSite() + * @generated + */ + EAttribute getECallSite_BytecodeIndex(); + + /** + * Returns the meta object for the reference '{@link com.ibm.wala.ecore.java.ECallSite#getJavaMethod Java Method}'. + * + * + * @return the meta object for the reference 'Java Method'. + * @see com.ibm.wala.ecore.java.ECallSite#getJavaMethod() + * @see #getECallSite() + * @generated + */ + EReference getECallSite_JavaMethod(); + + /** + * Returns the meta object for the reference '{@link com.ibm.wala.ecore.java.ECallSite#getDeclaredTarget Declared Target}'. + * + * + * @return the meta object for the reference 'Declared Target'. + * @see com.ibm.wala.ecore.java.ECallSite#getDeclaredTarget() + * @see #getECallSite() + * @generated + */ + EReference getECallSite_DeclaredTarget(); + + /** + * Returns the meta object for class '{@link com.ibm.wala.ecore.java.EClassHierarchy EClass Hierarchy}'. + * + * + * @return the meta object for class 'EClass Hierarchy'. + * @see com.ibm.wala.ecore.java.EClassHierarchy + * @generated + */ + EClass getEClassHierarchy(); + + /** + * Returns the meta object for class '{@link com.ibm.wala.ecore.java.EInterfaceHierarchy EInterface Hierarchy}'. + * + * + * @return the meta object for class 'EInterface Hierarchy'. + * @see com.ibm.wala.ecore.java.EInterfaceHierarchy + * @generated + */ + EClass getEInterfaceHierarchy(); + + /** + * Returns the meta object for class '{@link com.ibm.wala.ecore.java.ETypeHierarchy EType Hierarchy}'. + * + * + * @return the meta object for class 'EType Hierarchy'. + * @see com.ibm.wala.ecore.java.ETypeHierarchy + * @generated + */ + EClass getETypeHierarchy(); + + /** + * Returns the meta object for the containment reference '{@link com.ibm.wala.ecore.java.ETypeHierarchy#getClasses Classes}'. + * + * + * @return the meta object for the containment reference 'Classes'. + * @see com.ibm.wala.ecore.java.ETypeHierarchy#getClasses() + * @see #getETypeHierarchy() + * @generated + */ + EReference getETypeHierarchy_Classes(); + + /** + * Returns the meta object for the containment reference '{@link com.ibm.wala.ecore.java.ETypeHierarchy#getInterfaces Interfaces}'. + * + * + * @return the meta object for the containment reference 'Interfaces'. + * @see com.ibm.wala.ecore.java.ETypeHierarchy#getInterfaces() + * @see #getETypeHierarchy() + * @generated + */ + EReference getETypeHierarchy_Interfaces(); + + /** + * Returns the meta object for the containment reference '{@link com.ibm.wala.ecore.java.ETypeHierarchy#getImplements Implements}'. + * + * + * @return the meta object for the containment reference 'Implements'. + * @see com.ibm.wala.ecore.java.ETypeHierarchy#getImplements() + * @see #getETypeHierarchy() + * @generated + */ + EReference getETypeHierarchy_Implements(); + + /** + * Returns the meta object for enum '{@link com.ibm.wala.ecore.java.EClassLoaderName EClass Loader Name}'. + * + * + * @return the meta object for enum 'EClass Loader Name'. + * @see com.ibm.wala.ecore.java.EClassLoaderName + * @generated + */ + EEnum getEClassLoaderName(); + + /** + * Returns the factory that creates the instances of the model. + * + * + * @return the factory that creates the instances of the model. + * @generated + */ + JavaFactory getJavaFactory(); + + /** + * + * Defines literals for the meta objects that represent + *
                                + *
                              • each class,
                              • + *
                              • each feature of each class,
                              • + *
                              • each enum,
                              • + *
                              • and each data type
                              • + *
                              + * + * @generated + */ + interface Literals { + /** + * The meta object literal for the '{@link com.ibm.wala.ecore.java.impl.EJavaClassImpl EJava Class}' class. + * + * + * @see com.ibm.wala.ecore.java.impl.EJavaClassImpl + * @see com.ibm.wala.ecore.java.impl.JavaPackageImpl#getEJavaClass() + * @generated + */ + EClass EJAVA_CLASS = eINSTANCE.getEJavaClass(); + + /** + * The meta object literal for the 'Class Name' attribute feature. + * + * + * @generated + */ + EAttribute EJAVA_CLASS__CLASS_NAME = eINSTANCE.getEJavaClass_ClassName(); + + /** + * The meta object literal for the 'Loader' attribute feature. + * + * + * @generated + */ + EAttribute EJAVA_CLASS__LOADER = eINSTANCE.getEJavaClass_Loader(); + + /** + * The meta object literal for the '{@link com.ibm.wala.ecore.java.impl.EJavaMethodImpl EJava Method}' class. + * + * + * @see com.ibm.wala.ecore.java.impl.EJavaMethodImpl + * @see com.ibm.wala.ecore.java.impl.JavaPackageImpl#getEJavaMethod() + * @generated + */ + EClass EJAVA_METHOD = eINSTANCE.getEJavaMethod(); + + /** + * The meta object literal for the 'Method Name' attribute feature. + * + * + * @generated + */ + EAttribute EJAVA_METHOD__METHOD_NAME = eINSTANCE.getEJavaMethod_MethodName(); + + /** + * The meta object literal for the 'Descriptor' attribute feature. + * + * + * @generated + */ + EAttribute EJAVA_METHOD__DESCRIPTOR = eINSTANCE.getEJavaMethod_Descriptor(); + + /** + * The meta object literal for the 'Java Class' reference feature. + * + * + * @generated + */ + EReference EJAVA_METHOD__JAVA_CLASS = eINSTANCE.getEJavaMethod_JavaClass(); + + /** + * The meta object literal for the 'Signature' attribute feature. + * + * + * @generated + */ + EAttribute EJAVA_METHOD__SIGNATURE = eINSTANCE.getEJavaMethod_Signature(); + + /** + * The meta object literal for the '{@link com.ibm.wala.ecore.java.impl.ECallSiteImpl ECall Site}' class. + * + * + * @see com.ibm.wala.ecore.java.impl.ECallSiteImpl + * @see com.ibm.wala.ecore.java.impl.JavaPackageImpl#getECallSite() + * @generated + */ + EClass ECALL_SITE = eINSTANCE.getECallSite(); + + /** + * The meta object literal for the 'Bytecode Index' attribute feature. + * + * + * @generated + */ + EAttribute ECALL_SITE__BYTECODE_INDEX = eINSTANCE.getECallSite_BytecodeIndex(); + + /** + * The meta object literal for the 'Java Method' reference feature. + * + * + * @generated + */ + EReference ECALL_SITE__JAVA_METHOD = eINSTANCE.getECallSite_JavaMethod(); + + /** + * The meta object literal for the 'Declared Target' reference feature. + * + * + * @generated + */ + EReference ECALL_SITE__DECLARED_TARGET = eINSTANCE.getECallSite_DeclaredTarget(); + + /** + * The meta object literal for the '{@link com.ibm.wala.ecore.java.impl.EClassHierarchyImpl EClass Hierarchy}' class. + * + * + * @see com.ibm.wala.ecore.java.impl.EClassHierarchyImpl + * @see com.ibm.wala.ecore.java.impl.JavaPackageImpl#getEClassHierarchy() + * @generated + */ + EClass ECLASS_HIERARCHY = eINSTANCE.getEClassHierarchy(); + + /** + * The meta object literal for the '{@link com.ibm.wala.ecore.java.impl.EInterfaceHierarchyImpl EInterface Hierarchy}' class. + * + * + * @see com.ibm.wala.ecore.java.impl.EInterfaceHierarchyImpl + * @see com.ibm.wala.ecore.java.impl.JavaPackageImpl#getEInterfaceHierarchy() + * @generated + */ + EClass EINTERFACE_HIERARCHY = eINSTANCE.getEInterfaceHierarchy(); + + /** + * The meta object literal for the '{@link com.ibm.wala.ecore.java.impl.ETypeHierarchyImpl EType Hierarchy}' class. + * + * + * @see com.ibm.wala.ecore.java.impl.ETypeHierarchyImpl + * @see com.ibm.wala.ecore.java.impl.JavaPackageImpl#getETypeHierarchy() + * @generated + */ + EClass ETYPE_HIERARCHY = eINSTANCE.getETypeHierarchy(); + + /** + * The meta object literal for the 'Classes' containment reference feature. + * + * + * @generated + */ + EReference ETYPE_HIERARCHY__CLASSES = eINSTANCE.getETypeHierarchy_Classes(); + + /** + * The meta object literal for the 'Interfaces' containment reference feature. + * + * + * @generated + */ + EReference ETYPE_HIERARCHY__INTERFACES = eINSTANCE.getETypeHierarchy_Interfaces(); + + /** + * The meta object literal for the 'Implements' containment reference feature. + * + * + * @generated + */ + EReference ETYPE_HIERARCHY__IMPLEMENTS = eINSTANCE.getETypeHierarchy_Implements(); + + /** + * The meta object literal for the '{@link com.ibm.wala.ecore.java.EClassLoaderName EClass Loader Name}' enum. + * + * + * @see com.ibm.wala.ecore.java.EClassLoaderName + * @see com.ibm.wala.ecore.java.impl.JavaPackageImpl#getEClassLoaderName() + * @generated + */ + EEnum ECLASS_LOADER_NAME = eINSTANCE.getEClassLoaderName(); + + } + +} //JavaPackage diff --git a/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/callGraph/CallGraphFactory.java b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/callGraph/CallGraphFactory.java new file mode 100644 index 000000000..ecdb525b0 --- /dev/null +++ b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/callGraph/CallGraphFactory.java @@ -0,0 +1,46 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java.callGraph; + +import org.eclipse.emf.ecore.EFactory; + +/** + * + * The Factory for the model. + * It provides a create method for each non-abstract class of the model. + * + * @see com.ibm.wala.ecore.java.callGraph.CallGraphPackage + * @generated + */ +public interface CallGraphFactory extends EFactory { + /** + * The singleton instance of the factory. + * + * + * @generated + */ + CallGraphFactory eINSTANCE = com.ibm.wala.ecore.java.callGraph.impl.CallGraphFactoryImpl.init(); + + /** + * Returns a new object of class 'ECall Graph'. + * + * + * @return a new object of class 'ECall Graph'. + * @generated + */ + ECallGraph createECallGraph(); + + /** + * Returns the package supported by this factory. + * + * + * @return the package supported by this factory. + * @generated + */ + CallGraphPackage getCallGraphPackage(); + +} //CallGraphFactory diff --git a/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/callGraph/CallGraphPackage.java b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/callGraph/CallGraphPackage.java new file mode 100644 index 000000000..0160c19a5 --- /dev/null +++ b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/callGraph/CallGraphPackage.java @@ -0,0 +1,173 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java.callGraph; + +import com.ibm.wala.ecore.graph.GraphPackage; + +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EPackage; +import org.eclipse.emf.ecore.EReference; + +/** + * + * The Package for the model. + * It contains accessors for the meta objects to represent + *
                                + *
                              • each class,
                              • + *
                              • each feature of each class,
                              • + *
                              • each enum,
                              • + *
                              • and each data type
                              • + *
                              + * + * @see com.ibm.wala.ecore.java.callGraph.CallGraphFactory + * @model kind="package" + * @generated + */ +public interface CallGraphPackage extends EPackage { + /** + * The package name. + * + * + * @generated + */ + String eNAME = "callGraph"; + + /** + * The package namespace URI. + * + * + * @generated + */ + String eNS_URI = "http:///com/ibm/wala/wala.ecore.java.callGraph"; + + /** + * The package namespace name. + * + * + * @generated + */ + String eNS_PREFIX = "com.ibm.wala.java.callGraph"; + + /** + * The singleton instance of the package. + * + * + * @generated + */ + CallGraphPackage eINSTANCE = com.ibm.wala.ecore.java.callGraph.impl.CallGraphPackageImpl.init(); + + /** + * The meta object id for the '{@link com.ibm.wala.ecore.java.callGraph.impl.ECallGraphImpl ECall Graph}' class. + * + * + * @see com.ibm.wala.ecore.java.callGraph.impl.ECallGraphImpl + * @see com.ibm.wala.ecore.java.callGraph.impl.CallGraphPackageImpl#getECallGraph() + * @generated + */ + int ECALL_GRAPH = 0; + + /** + * The feature id for the 'Nodes' reference. + * + * + * @generated + * @ordered + */ + int ECALL_GRAPH__NODES = GraphPackage.EGRAPH__NODES; + + /** + * The feature id for the 'Edges' containment reference. + * + * + * @generated + * @ordered + */ + int ECALL_GRAPH__EDGES = GraphPackage.EGRAPH__EDGES; + + /** + * The feature id for the 'Entrypoints' reference list. + * + * + * @generated + * @ordered + */ + int ECALL_GRAPH__ENTRYPOINTS = GraphPackage.EGRAPH_FEATURE_COUNT + 0; + + /** + * The number of structural features of the 'ECall Graph' class. + * + * + * @generated + * @ordered + */ + int ECALL_GRAPH_FEATURE_COUNT = GraphPackage.EGRAPH_FEATURE_COUNT + 1; + + + /** + * Returns the meta object for class '{@link com.ibm.wala.ecore.java.callGraph.ECallGraph ECall Graph}'. + * + * + * @return the meta object for class 'ECall Graph'. + * @see com.ibm.wala.ecore.java.callGraph.ECallGraph + * @generated + */ + EClass getECallGraph(); + + /** + * Returns the meta object for the reference list '{@link com.ibm.wala.ecore.java.callGraph.ECallGraph#getEntrypoints Entrypoints}'. + * + * + * @return the meta object for the reference list 'Entrypoints'. + * @see com.ibm.wala.ecore.java.callGraph.ECallGraph#getEntrypoints() + * @see #getECallGraph() + * @generated + */ + EReference getECallGraph_Entrypoints(); + + /** + * Returns the factory that creates the instances of the model. + * + * + * @return the factory that creates the instances of the model. + * @generated + */ + CallGraphFactory getCallGraphFactory(); + + /** + * + * Defines literals for the meta objects that represent + *
                                + *
                              • each class,
                              • + *
                              • each feature of each class,
                              • + *
                              • each enum,
                              • + *
                              • and each data type
                              • + *
                              + * + * @generated + */ + interface Literals { + /** + * The meta object literal for the '{@link com.ibm.wala.ecore.java.callGraph.impl.ECallGraphImpl ECall Graph}' class. + * + * + * @see com.ibm.wala.ecore.java.callGraph.impl.ECallGraphImpl + * @see com.ibm.wala.ecore.java.callGraph.impl.CallGraphPackageImpl#getECallGraph() + * @generated + */ + EClass ECALL_GRAPH = eINSTANCE.getECallGraph(); + + /** + * The meta object literal for the 'Entrypoints' reference list feature. + * + * + * @generated + */ + EReference ECALL_GRAPH__ENTRYPOINTS = eINSTANCE.getECallGraph_Entrypoints(); + + } + +} //CallGraphPackage diff --git a/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/callGraph/ECallGraph.java b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/callGraph/ECallGraph.java new file mode 100644 index 000000000..3571cb7c4 --- /dev/null +++ b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/callGraph/ECallGraph.java @@ -0,0 +1,46 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java.callGraph; + +import com.ibm.wala.ecore.graph.EGraph; + +import org.eclipse.emf.common.util.EList; + +/** + * + * A representation of the model object 'ECall Graph'. + * + * + *

                              + * The following features are supported: + *

                                + *
                              • {@link com.ibm.wala.ecore.java.callGraph.ECallGraph#getEntrypoints Entrypoints}
                              • + *
                              + *

                              + * + * @see com.ibm.wala.ecore.java.callGraph.CallGraphPackage#getECallGraph() + * @model + * @generated + */ +public interface ECallGraph extends EGraph { + /** + * Returns the value of the 'Entrypoints' reference list. + * The list contents are of type {@link com.ibm.wala.ecore.java.EJavaMethod}. + * + *

                              + * If the meaning of the 'Entrypoints' reference list isn't clear, + * there really should be more of a description here... + *

                              + * + * @return the value of the 'Entrypoints' reference list. + * @see com.ibm.wala.ecore.java.callGraph.CallGraphPackage#getECallGraph_Entrypoints() + * @model type="com.ibm.wala.ecore.java.EJavaMethod" + * @generated + */ + EList getEntrypoints(); + +} // ECallGraph \ No newline at end of file diff --git a/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/callGraph/impl/CallGraphFactoryImpl.java b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/callGraph/impl/CallGraphFactoryImpl.java new file mode 100644 index 000000000..cb20e2087 --- /dev/null +++ b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/callGraph/impl/CallGraphFactoryImpl.java @@ -0,0 +1,97 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java.callGraph.impl; + +import com.ibm.wala.ecore.java.callGraph.*; + +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EPackage; + +import org.eclipse.emf.ecore.impl.EFactoryImpl; + +import org.eclipse.emf.ecore.plugin.EcorePlugin; + +/** + * + * An implementation of the model Factory. + * + * @generated + */ +public class CallGraphFactoryImpl extends EFactoryImpl implements CallGraphFactory { + /** + * Creates the default factory implementation. + * + * + * @generated + */ + public static CallGraphFactory init() { + try { + CallGraphFactory theCallGraphFactory = (CallGraphFactory)EPackage.Registry.INSTANCE.getEFactory("http:///com/ibm/wala/wala.ecore.java.callGraph"); + if (theCallGraphFactory != null) { + return theCallGraphFactory; + } + } + catch (Exception exception) { + EcorePlugin.INSTANCE.log(exception); + } + return new CallGraphFactoryImpl(); + } + + /** + * Creates an instance of the factory. + * + * + * @generated + */ + public CallGraphFactoryImpl() { + super(); + } + + /** + * + * + * @generated + */ + public EObject create(EClass eClass) { + switch (eClass.getClassifierID()) { + case CallGraphPackage.ECALL_GRAPH: return createECallGraph(); + default: + throw new IllegalArgumentException("The class '" + eClass.getName() + "' is not a valid classifier"); + } + } + + /** + * + * + * @generated + */ + public ECallGraph createECallGraph() { + ECallGraphImpl eCallGraph = new ECallGraphImpl(); + return eCallGraph; + } + + /** + * + * + * @generated + */ + public CallGraphPackage getCallGraphPackage() { + return (CallGraphPackage)getEPackage(); + } + + /** + * + * + * @deprecated + * @generated + */ + public static CallGraphPackage getPackage() { + return CallGraphPackage.eINSTANCE; + } + +} //CallGraphFactoryImpl diff --git a/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/callGraph/impl/CallGraphPackageImpl.java b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/callGraph/impl/CallGraphPackageImpl.java new file mode 100644 index 000000000..ce63f9c20 --- /dev/null +++ b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/callGraph/impl/CallGraphPackageImpl.java @@ -0,0 +1,244 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java.callGraph.impl; + +import com.ibm.wala.ecore.common.CommonPackage; + +import com.ibm.wala.ecore.common.impl.CommonPackageImpl; + +import com.ibm.wala.ecore.graph.GraphPackage; + +import com.ibm.wala.ecore.graph.impl.GraphPackageImpl; + +import com.ibm.wala.ecore.j2ee.scope.J2EEScopePackage; + +import com.ibm.wala.ecore.j2ee.scope.impl.J2EEScopePackageImpl; + +import com.ibm.wala.ecore.java.JavaPackage; + +import com.ibm.wala.ecore.java.callGraph.CallGraphFactory; +import com.ibm.wala.ecore.java.callGraph.CallGraphPackage; +import com.ibm.wala.ecore.java.callGraph.ECallGraph; + +import com.ibm.wala.ecore.java.impl.JavaPackageImpl; + +import com.ibm.wala.ecore.java.pointerAnalysis.PointerAnalysisPackage; + +import com.ibm.wala.ecore.java.pointerAnalysis.impl.PointerAnalysisPackageImpl; + +import com.ibm.wala.ecore.java.scope.JavaScopePackage; + +import com.ibm.wala.ecore.java.scope.impl.JavaScopePackageImpl; + +import com.ibm.wala.ecore.perf.PerfPackage; + +import com.ibm.wala.ecore.perf.impl.PerfPackageImpl; + +import com.ibm.wala.ecore.regex.RegexPackage; + +import com.ibm.wala.ecore.regex.impl.RegexPackageImpl; + +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EPackage; +import org.eclipse.emf.ecore.EReference; + +import org.eclipse.emf.ecore.impl.EPackageImpl; + +/** + * + * An implementation of the model Package. + * + * @generated + */ +public class CallGraphPackageImpl extends EPackageImpl implements CallGraphPackage { + /** + * + * + * @generated + */ + private EClass eCallGraphEClass = null; + + /** + * Creates an instance of the model Package, registered with + * {@link org.eclipse.emf.ecore.EPackage.Registry EPackage.Registry} by the package + * package URI value. + *

                              Note: the correct way to create the package is via the static + * factory method {@link #init init()}, which also performs + * initialization of the package, or returns the registered package, + * if one already exists. + * + * + * @see org.eclipse.emf.ecore.EPackage.Registry + * @see com.ibm.wala.ecore.java.callGraph.CallGraphPackage#eNS_URI + * @see #init() + * @generated + */ + private CallGraphPackageImpl() { + super(eNS_URI, CallGraphFactory.eINSTANCE); + } + + /** + * + * + * @generated + */ + private static boolean isInited = false; + + /** + * Creates, registers, and initializes the Package for this + * model, and for any others upon which it depends. Simple + * dependencies are satisfied by calling this method on all + * dependent packages before doing anything else. This method drives + * initialization for interdependent packages directly, in parallel + * with this package, itself. + *

                              Of this package and its interdependencies, all packages which + * have not yet been registered by their URI values are first created + * and registered. The packages are then initialized in two steps: + * meta-model objects for all of the packages are created before any + * are initialized, since one package's meta-model objects may refer to + * those of another. + *

                              Invocation of this method will not affect any packages that have + * already been initialized. + * + * + * @see #eNS_URI + * @see #createPackageContents() + * @see #initializePackageContents() + * @generated + */ + public static CallGraphPackage init() { + if (isInited) return (CallGraphPackage)EPackage.Registry.INSTANCE.getEPackage(CallGraphPackage.eNS_URI); + + // Obtain or create and register package + CallGraphPackageImpl theCallGraphPackage = (CallGraphPackageImpl)(EPackage.Registry.INSTANCE.getEPackage(eNS_URI) instanceof CallGraphPackageImpl ? EPackage.Registry.INSTANCE.getEPackage(eNS_URI) : new CallGraphPackageImpl()); + + isInited = true; + + // Obtain or create and register interdependencies + GraphPackageImpl theGraphPackage = (GraphPackageImpl)(EPackage.Registry.INSTANCE.getEPackage(GraphPackage.eNS_URI) instanceof GraphPackageImpl ? EPackage.Registry.INSTANCE.getEPackage(GraphPackage.eNS_URI) : GraphPackage.eINSTANCE); + CommonPackageImpl theCommonPackage = (CommonPackageImpl)(EPackage.Registry.INSTANCE.getEPackage(CommonPackage.eNS_URI) instanceof CommonPackageImpl ? EPackage.Registry.INSTANCE.getEPackage(CommonPackage.eNS_URI) : CommonPackage.eINSTANCE); + RegexPackageImpl theRegexPackage = (RegexPackageImpl)(EPackage.Registry.INSTANCE.getEPackage(RegexPackage.eNS_URI) instanceof RegexPackageImpl ? EPackage.Registry.INSTANCE.getEPackage(RegexPackage.eNS_URI) : RegexPackage.eINSTANCE); + PerfPackageImpl thePerfPackage = (PerfPackageImpl)(EPackage.Registry.INSTANCE.getEPackage(PerfPackage.eNS_URI) instanceof PerfPackageImpl ? EPackage.Registry.INSTANCE.getEPackage(PerfPackage.eNS_URI) : PerfPackage.eINSTANCE); + JavaPackageImpl theJavaPackage = (JavaPackageImpl)(EPackage.Registry.INSTANCE.getEPackage(JavaPackage.eNS_URI) instanceof JavaPackageImpl ? EPackage.Registry.INSTANCE.getEPackage(JavaPackage.eNS_URI) : JavaPackage.eINSTANCE); + PointerAnalysisPackageImpl thePointerAnalysisPackage = (PointerAnalysisPackageImpl)(EPackage.Registry.INSTANCE.getEPackage(PointerAnalysisPackage.eNS_URI) instanceof PointerAnalysisPackageImpl ? EPackage.Registry.INSTANCE.getEPackage(PointerAnalysisPackage.eNS_URI) : PointerAnalysisPackage.eINSTANCE); + JavaScopePackageImpl theJavaScopePackage = (JavaScopePackageImpl)(EPackage.Registry.INSTANCE.getEPackage(JavaScopePackage.eNS_URI) instanceof JavaScopePackageImpl ? EPackage.Registry.INSTANCE.getEPackage(JavaScopePackage.eNS_URI) : JavaScopePackage.eINSTANCE); + J2EEScopePackageImpl theJ2EEScopePackage = (J2EEScopePackageImpl)(EPackage.Registry.INSTANCE.getEPackage(J2EEScopePackage.eNS_URI) instanceof J2EEScopePackageImpl ? EPackage.Registry.INSTANCE.getEPackage(J2EEScopePackage.eNS_URI) : J2EEScopePackage.eINSTANCE); + + // Create package meta-data objects + theCallGraphPackage.createPackageContents(); + theGraphPackage.createPackageContents(); + theCommonPackage.createPackageContents(); + theRegexPackage.createPackageContents(); + thePerfPackage.createPackageContents(); + theJavaPackage.createPackageContents(); + thePointerAnalysisPackage.createPackageContents(); + theJavaScopePackage.createPackageContents(); + theJ2EEScopePackage.createPackageContents(); + + // Initialize created meta-data + theCallGraphPackage.initializePackageContents(); + theGraphPackage.initializePackageContents(); + theCommonPackage.initializePackageContents(); + theRegexPackage.initializePackageContents(); + thePerfPackage.initializePackageContents(); + theJavaPackage.initializePackageContents(); + thePointerAnalysisPackage.initializePackageContents(); + theJavaScopePackage.initializePackageContents(); + theJ2EEScopePackage.initializePackageContents(); + + // Mark meta-data to indicate it can't be changed + theCallGraphPackage.freeze(); + + return theCallGraphPackage; + } + + /** + * + * + * @generated + */ + public EClass getECallGraph() { + return eCallGraphEClass; + } + + /** + * + * + * @generated + */ + public EReference getECallGraph_Entrypoints() { + return (EReference)eCallGraphEClass.getEStructuralFeatures().get(0); + } + + /** + * + * + * @generated + */ + public CallGraphFactory getCallGraphFactory() { + return (CallGraphFactory)getEFactoryInstance(); + } + + /** + * + * + * @generated + */ + private boolean isCreated = false; + + /** + * Creates the meta-model objects for the package. This method is + * guarded to have no affect on any invocation but its first. + * + * + * @generated + */ + public void createPackageContents() { + if (isCreated) return; + isCreated = true; + + // Create classes and their features + eCallGraphEClass = createEClass(ECALL_GRAPH); + createEReference(eCallGraphEClass, ECALL_GRAPH__ENTRYPOINTS); + } + + /** + * + * + * @generated + */ + private boolean isInitialized = false; + + /** + * Complete the initialization of the package and its meta-model. This + * method is guarded to have no affect on any invocation but its first. + * + * + * @generated + */ + public void initializePackageContents() { + if (isInitialized) return; + isInitialized = true; + + // Initialize package + setName(eNAME); + setNsPrefix(eNS_PREFIX); + setNsURI(eNS_URI); + + // Obtain other dependent packages + GraphPackage theGraphPackage = (GraphPackage)EPackage.Registry.INSTANCE.getEPackage(GraphPackage.eNS_URI); + JavaPackage theJavaPackage = (JavaPackage)EPackage.Registry.INSTANCE.getEPackage(JavaPackage.eNS_URI); + + // Add supertypes to classes + eCallGraphEClass.getESuperTypes().add(theGraphPackage.getEGraph()); + + // Initialize classes and features; add operations and parameters + initEClass(eCallGraphEClass, ECallGraph.class, "ECallGraph", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); + initEReference(getECallGraph_Entrypoints(), theJavaPackage.getEJavaMethod(), null, "entrypoints", null, 0, -1, ECallGraph.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_COMPOSITE, IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); + } + +} //CallGraphPackageImpl diff --git a/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/callGraph/impl/ECallGraphImpl.java b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/callGraph/impl/ECallGraphImpl.java new file mode 100644 index 000000000..511f432a0 --- /dev/null +++ b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/callGraph/impl/ECallGraphImpl.java @@ -0,0 +1,133 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java.callGraph.impl; + +import com.ibm.wala.ecore.graph.impl.EGraphImpl; + +import com.ibm.wala.ecore.java.EJavaMethod; + +import com.ibm.wala.ecore.java.callGraph.CallGraphPackage; +import com.ibm.wala.ecore.java.callGraph.ECallGraph; + +import java.util.Collection; + +import org.eclipse.emf.common.util.EList; + +import org.eclipse.emf.ecore.EClass; + +import org.eclipse.emf.ecore.util.EObjectResolvingEList; + +/** + * + * An implementation of the model object 'ECall Graph'. + * + *

                              + * The following features are implemented: + *

                                + *
                              • {@link com.ibm.wala.ecore.java.callGraph.impl.ECallGraphImpl#getEntrypoints Entrypoints}
                              • + *
                              + *

                              + * + * @generated + */ +public class ECallGraphImpl extends EGraphImpl implements ECallGraph { + /** + * The cached value of the '{@link #getEntrypoints() Entrypoints}' reference list. + * + * + * @see #getEntrypoints() + * @generated + * @ordered + */ + protected EList entrypoints = null; + + /** + * + * + * @generated + */ + protected ECallGraphImpl() { + super(); + } + + /** + * + * + * @generated + */ + protected EClass eStaticClass() { + return CallGraphPackage.Literals.ECALL_GRAPH; + } + + /** + * + * + * @generated + */ + public EList getEntrypoints() { + if (entrypoints == null) { + entrypoints = new EObjectResolvingEList(EJavaMethod.class, this, CallGraphPackage.ECALL_GRAPH__ENTRYPOINTS); + } + return entrypoints; + } + + /** + * + * + * @generated + */ + public Object eGet(int featureID, boolean resolve, boolean coreType) { + switch (featureID) { + case CallGraphPackage.ECALL_GRAPH__ENTRYPOINTS: + return getEntrypoints(); + } + return super.eGet(featureID, resolve, coreType); + } + + /** + * + * + * @generated + */ + public void eSet(int featureID, Object newValue) { + switch (featureID) { + case CallGraphPackage.ECALL_GRAPH__ENTRYPOINTS: + getEntrypoints().clear(); + getEntrypoints().addAll((Collection)newValue); + return; + } + super.eSet(featureID, newValue); + } + + /** + * + * + * @generated + */ + public void eUnset(int featureID) { + switch (featureID) { + case CallGraphPackage.ECALL_GRAPH__ENTRYPOINTS: + getEntrypoints().clear(); + return; + } + super.eUnset(featureID); + } + + /** + * + * + * @generated + */ + public boolean eIsSet(int featureID) { + switch (featureID) { + case CallGraphPackage.ECALL_GRAPH__ENTRYPOINTS: + return entrypoints != null && !entrypoints.isEmpty(); + } + return super.eIsSet(featureID); + } + +} //ECallGraphImpl \ No newline at end of file diff --git a/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/callGraph/util/CallGraphAdapterFactory.java b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/callGraph/util/CallGraphAdapterFactory.java new file mode 100644 index 000000000..b1b3d1669 --- /dev/null +++ b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/callGraph/util/CallGraphAdapterFactory.java @@ -0,0 +1,139 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java.callGraph.util; + +import com.ibm.wala.ecore.graph.EGraph; + +import com.ibm.wala.ecore.java.callGraph.*; + +import org.eclipse.emf.common.notify.Adapter; +import org.eclipse.emf.common.notify.Notifier; + +import org.eclipse.emf.common.notify.impl.AdapterFactoryImpl; + +import org.eclipse.emf.ecore.EObject; + +/** + * + * The Adapter Factory for the model. + * It provides an adapter createXXX method for each class of the model. + * + * @see com.ibm.wala.ecore.java.callGraph.CallGraphPackage + * @generated + */ +public class CallGraphAdapterFactory extends AdapterFactoryImpl { + /** + * The cached model package. + * + * + * @generated + */ + protected static CallGraphPackage modelPackage; + + /** + * Creates an instance of the adapter factory. + * + * + * @generated + */ + public CallGraphAdapterFactory() { + if (modelPackage == null) { + modelPackage = CallGraphPackage.eINSTANCE; + } + } + + /** + * Returns whether this factory is applicable for the type of the object. + * + * This implementation returns true if the object is either the model's package or is an instance object of the model. + * + * @return whether this factory is applicable for the type of the object. + * @generated + */ + public boolean isFactoryForType(Object object) { + if (object == modelPackage) { + return true; + } + if (object instanceof EObject) { + return ((EObject)object).eClass().getEPackage() == modelPackage; + } + return false; + } + + /** + * The switch the delegates to the createXXX methods. + * + * + * @generated + */ + protected CallGraphSwitch modelSwitch = + new CallGraphSwitch() { + public Object caseECallGraph(ECallGraph object) { + return createECallGraphAdapter(); + } + public Object caseEGraph(EGraph object) { + return createEGraphAdapter(); + } + public Object defaultCase(EObject object) { + return createEObjectAdapter(); + } + }; + + /** + * Creates an adapter for the target. + * + * + * @param target the object to adapt. + * @return the adapter for the target. + * @generated + */ + public Adapter createAdapter(Notifier target) { + return (Adapter)modelSwitch.doSwitch((EObject)target); + } + + + /** + * Creates a new adapter for an object of class '{@link com.ibm.wala.ecore.java.callGraph.ECallGraph ECall Graph}'. + * + * This default implementation returns null so that we can easily ignore cases; + * it's useful to ignore a case when inheritance will catch all the cases anyway. + * + * @return the new adapter. + * @see com.ibm.wala.ecore.java.callGraph.ECallGraph + * @generated + */ + public Adapter createECallGraphAdapter() { + return null; + } + + /** + * Creates a new adapter for an object of class '{@link com.ibm.wala.ecore.graph.EGraph EGraph}'. + * + * This default implementation returns null so that we can easily ignore cases; + * it's useful to ignore a case when inheritance will catch all the cases anyway. + * + * @return the new adapter. + * @see com.ibm.wala.ecore.graph.EGraph + * @generated + */ + public Adapter createEGraphAdapter() { + return null; + } + + /** + * Creates a new adapter for the default case. + * + * This default implementation returns null. + * + * @return the new adapter. + * @generated + */ + public Adapter createEObjectAdapter() { + return null; + } + +} //CallGraphAdapterFactory diff --git a/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/callGraph/util/CallGraphSwitch.java b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/callGraph/util/CallGraphSwitch.java new file mode 100644 index 000000000..86f8048ce --- /dev/null +++ b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/callGraph/util/CallGraphSwitch.java @@ -0,0 +1,148 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java.callGraph.util; + +import com.ibm.wala.ecore.graph.EGraph; + +import com.ibm.wala.ecore.java.callGraph.*; + +import java.util.List; + +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EObject; + +/** + * + * The Switch for the model's inheritance hierarchy. + * It supports the call {@link #doSwitch(EObject) doSwitch(object)} + * to invoke the caseXXX method for each class of the model, + * starting with the actual class of the object + * and proceeding up the inheritance hierarchy + * until a non-null result is returned, + * which is the result of the switch. + * + * @see com.ibm.wala.ecore.java.callGraph.CallGraphPackage + * @generated + */ +public class CallGraphSwitch { + /** + * The cached model package + * + * + * @generated + */ + protected static CallGraphPackage modelPackage; + + /** + * Creates an instance of the switch. + * + * + * @generated + */ + public CallGraphSwitch() { + if (modelPackage == null) { + modelPackage = CallGraphPackage.eINSTANCE; + } + } + + /** + * Calls caseXXX for each class of the model until one returns a non null result; it yields that result. + * + * + * @return the first non-null result returned by a caseXXX call. + * @generated + */ + public Object doSwitch(EObject theEObject) { + return doSwitch(theEObject.eClass(), theEObject); + } + + /** + * Calls caseXXX for each class of the model until one returns a non null result; it yields that result. + * + * + * @return the first non-null result returned by a caseXXX call. + * @generated + */ + protected Object doSwitch(EClass theEClass, EObject theEObject) { + if (theEClass.eContainer() == modelPackage) { + return doSwitch(theEClass.getClassifierID(), theEObject); + } + else { + List eSuperTypes = theEClass.getESuperTypes(); + return + eSuperTypes.isEmpty() ? + defaultCase(theEObject) : + doSwitch((EClass)eSuperTypes.get(0), theEObject); + } + } + + /** + * Calls caseXXX for each class of the model until one returns a non null result; it yields that result. + * + * + * @return the first non-null result returned by a caseXXX call. + * @generated + */ + protected Object doSwitch(int classifierID, EObject theEObject) { + switch (classifierID) { + case CallGraphPackage.ECALL_GRAPH: { + ECallGraph eCallGraph = (ECallGraph)theEObject; + Object result = caseECallGraph(eCallGraph); + if (result == null) result = caseEGraph(eCallGraph); + if (result == null) result = defaultCase(theEObject); + return result; + } + default: return defaultCase(theEObject); + } + } + + /** + * Returns the result of interpretting the object as an instance of 'ECall Graph'. + * + * This implementation returns null; + * returning a non-null result will terminate the switch. + * + * @param object the target of the switch. + * @return the result of interpretting the object as an instance of 'ECall Graph'. + * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject) + * @generated + */ + public Object caseECallGraph(ECallGraph object) { + return null; + } + + /** + * Returns the result of interpretting the object as an instance of 'EGraph'. + * + * This implementation returns null; + * returning a non-null result will terminate the switch. + * + * @param object the target of the switch. + * @return the result of interpretting the object as an instance of 'EGraph'. + * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject) + * @generated + */ + public Object caseEGraph(EGraph object) { + return null; + } + + /** + * Returns the result of interpretting the object as an instance of 'EObject'. + * + * This implementation returns null; + * returning a non-null result will terminate the switch, but this is the last case anyway. + * + * @param object the target of the switch. + * @return the result of interpretting the object as an instance of 'EObject'. + * @see #doSwitch(org.eclipse.emf.ecore.EObject) + * @generated + */ + public Object defaultCase(EObject object) { + return null; + } + +} //CallGraphSwitch diff --git a/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/impl/ECallSiteImpl.java b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/impl/ECallSiteImpl.java new file mode 100644 index 000000000..e8c432245 --- /dev/null +++ b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/impl/ECallSiteImpl.java @@ -0,0 +1,290 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java.impl; + +import com.ibm.wala.ecore.common.impl.EObjectWithContainerIdImpl; + +import com.ibm.wala.ecore.java.ECallSite; +import com.ibm.wala.ecore.java.EJavaMethod; +import com.ibm.wala.ecore.java.JavaPackage; + +import org.eclipse.emf.common.notify.Notification; + +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.InternalEObject; + +import org.eclipse.emf.ecore.impl.ENotificationImpl; + +/** + * An implementation of the model object 'ECall Site'. + * + *

                              + * The following features are implemented: + *

                                + *
                              • {@link com.ibm.wala.ecore.java.impl.ECallSiteImpl#getBytecodeIndex Bytecode Index}
                              • + *
                              • {@link com.ibm.wala.ecore.java.impl.ECallSiteImpl#getJavaMethod Java Method}
                              • + *
                              • {@link com.ibm.wala.ecore.java.impl.ECallSiteImpl#getDeclaredTarget Declared Target}
                              • + *
                              + *

                              + * + * @generated + */ +public class ECallSiteImpl extends EObjectWithContainerIdImpl implements ECallSite { + + /** + * The default value of the '{@link #getBytecodeIndex() Bytecode Index}' attribute. + * + * @see #getBytecodeIndex() + * @generated + * @ordered + */ + protected static final int BYTECODE_INDEX_EDEFAULT = 0; + + /** + * The cached value of the '{@link #getBytecodeIndex() Bytecode Index}' attribute. + * + * @see #getBytecodeIndex() + * @generated + * @ordered + */ + protected int bytecodeIndex = BYTECODE_INDEX_EDEFAULT; + + /** + * The cached value of the '{@link #getJavaMethod() Java Method}' reference. + * + * @see #getJavaMethod() + * @generated + * @ordered + */ + protected EJavaMethod javaMethod = null; + + /** + * The cached value of the '{@link #getDeclaredTarget() Declared Target}' reference. + * + * @see #getDeclaredTarget() + * @generated + * @ordered + */ + protected EJavaMethod declaredTarget = null; + + /** + * + * @generated + */ + protected ECallSiteImpl() { + super(); + } + + /** + * + * @generated + */ + protected EClass eStaticClass() { + return JavaPackage.Literals.ECALL_SITE; + } + + /** + * + * @generated + */ + public int getBytecodeIndex() { + return bytecodeIndex; + } + + /** + * + * @generated + */ + public void setBytecodeIndex(int newBytecodeIndex) { + int oldBytecodeIndex = bytecodeIndex; + bytecodeIndex = newBytecodeIndex; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, JavaPackage.ECALL_SITE__BYTECODE_INDEX, oldBytecodeIndex, bytecodeIndex)); + } + + /** + * + * @generated + */ + public EJavaMethod getJavaMethod() { + if (javaMethod != null && javaMethod.eIsProxy()) { + InternalEObject oldJavaMethod = (InternalEObject)javaMethod; + javaMethod = (EJavaMethod)eResolveProxy(oldJavaMethod); + if (javaMethod != oldJavaMethod) { + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.RESOLVE, JavaPackage.ECALL_SITE__JAVA_METHOD, oldJavaMethod, javaMethod)); + } + } + return javaMethod; + } + + /** + * + * @generated + */ + public EJavaMethod basicGetJavaMethod() { + return javaMethod; + } + + /** + * + * @generated + */ + public void setJavaMethod(EJavaMethod newJavaMethod) { + EJavaMethod oldJavaMethod = javaMethod; + javaMethod = newJavaMethod; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, JavaPackage.ECALL_SITE__JAVA_METHOD, oldJavaMethod, javaMethod)); + } + + /** + * + * @generated + */ + public EJavaMethod getDeclaredTarget() { + if (declaredTarget != null && declaredTarget.eIsProxy()) { + InternalEObject oldDeclaredTarget = (InternalEObject)declaredTarget; + declaredTarget = (EJavaMethod)eResolveProxy(oldDeclaredTarget); + if (declaredTarget != oldDeclaredTarget) { + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.RESOLVE, JavaPackage.ECALL_SITE__DECLARED_TARGET, oldDeclaredTarget, declaredTarget)); + } + } + return declaredTarget; + } + + /** + * + * @generated + */ + public EJavaMethod basicGetDeclaredTarget() { + return declaredTarget; + } + + /** + * + * @generated + */ + public void setDeclaredTarget(EJavaMethod newDeclaredTarget) { + EJavaMethod oldDeclaredTarget = declaredTarget; + declaredTarget = newDeclaredTarget; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, JavaPackage.ECALL_SITE__DECLARED_TARGET, oldDeclaredTarget, declaredTarget)); + } + + /** + * + * @generated + */ + public Object eGet(int featureID, boolean resolve, boolean coreType) { + switch (featureID) { + case JavaPackage.ECALL_SITE__BYTECODE_INDEX: + return new Integer(getBytecodeIndex()); + case JavaPackage.ECALL_SITE__JAVA_METHOD: + if (resolve) return getJavaMethod(); + return basicGetJavaMethod(); + case JavaPackage.ECALL_SITE__DECLARED_TARGET: + if (resolve) return getDeclaredTarget(); + return basicGetDeclaredTarget(); + } + return super.eGet(featureID, resolve, coreType); + } + + /** + * + * @generated + */ + public void eSet(int featureID, Object newValue) { + switch (featureID) { + case JavaPackage.ECALL_SITE__BYTECODE_INDEX: + setBytecodeIndex(((Integer)newValue).intValue()); + return; + case JavaPackage.ECALL_SITE__JAVA_METHOD: + setJavaMethod((EJavaMethod)newValue); + return; + case JavaPackage.ECALL_SITE__DECLARED_TARGET: + setDeclaredTarget((EJavaMethod)newValue); + return; + } + super.eSet(featureID, newValue); + } + + /** + * + * @generated + */ + public void eUnset(int featureID) { + switch (featureID) { + case JavaPackage.ECALL_SITE__BYTECODE_INDEX: + setBytecodeIndex(BYTECODE_INDEX_EDEFAULT); + return; + case JavaPackage.ECALL_SITE__JAVA_METHOD: + setJavaMethod((EJavaMethod)null); + return; + case JavaPackage.ECALL_SITE__DECLARED_TARGET: + setDeclaredTarget((EJavaMethod)null); + return; + } + super.eUnset(featureID); + } + + /** + * + * @generated + */ + public boolean eIsSet(int featureID) { + switch (featureID) { + case JavaPackage.ECALL_SITE__BYTECODE_INDEX: + return bytecodeIndex != BYTECODE_INDEX_EDEFAULT; + case JavaPackage.ECALL_SITE__JAVA_METHOD: + return javaMethod != null; + case JavaPackage.ECALL_SITE__DECLARED_TARGET: + return declaredTarget != null; + } + return super.eIsSet(featureID); + } + + /** + * + * @generated + */ + public String toString() { + if (eIsProxy()) return super.toString(); + + StringBuffer result = new StringBuffer(super.toString()); + result.append(" (bytecodeIndex: "); + result.append(bytecodeIndex); + result.append(')'); + return result.toString(); + } + + public boolean equals(Object obj) { + if (getClass().equals(obj.getClass())) { + ECallSiteImpl other = (ECallSiteImpl) obj; + if (bytecodeIndex != other.bytecodeIndex) { + return false; + } + if (!javaMethod.equals(other.javaMethod)) { + return false; + } + if (declaredTarget == null) { + return declaredTarget == null; + } + return declaredTarget.equals(other.declaredTarget); + } else { + return false; + } + + } + + public int hashCode() { + int result = bytecodeIndex + javaMethod.hashCode() * 1013; + result = (declaredTarget == null) ? result : result + 281*declaredTarget.hashCode(); + return result; + } + +} // ECallSiteImpl diff --git a/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/impl/EClassHierarchyImpl.java b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/impl/EClassHierarchyImpl.java new file mode 100644 index 000000000..3eefdc5c8 --- /dev/null +++ b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/impl/EClassHierarchyImpl.java @@ -0,0 +1,44 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java.impl; + +import com.ibm.wala.ecore.graph.impl.ETreeImpl; + +import com.ibm.wala.ecore.java.EClassHierarchy; +import com.ibm.wala.ecore.java.JavaPackage; + +import org.eclipse.emf.ecore.EClass; + +/** + * + * An implementation of the model object 'EClass Hierarchy'. + * + *

                              + *

                              + * + * @generated + */ +public class EClassHierarchyImpl extends ETreeImpl implements EClassHierarchy { + /** + * + * + * @generated + */ + protected EClassHierarchyImpl() { + super(); + } + + /** + * + * + * @generated + */ + protected EClass eStaticClass() { + return JavaPackage.Literals.ECLASS_HIERARCHY; + } + +} //EClassHierarchyImpl \ No newline at end of file diff --git a/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/impl/EInterfaceHierarchyImpl.java b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/impl/EInterfaceHierarchyImpl.java new file mode 100644 index 000000000..77ea15981 --- /dev/null +++ b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/impl/EInterfaceHierarchyImpl.java @@ -0,0 +1,44 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java.impl; + +import com.ibm.wala.ecore.graph.impl.EGraphImpl; + +import com.ibm.wala.ecore.java.EInterfaceHierarchy; +import com.ibm.wala.ecore.java.JavaPackage; + +import org.eclipse.emf.ecore.EClass; + +/** + * + * An implementation of the model object 'EInterface Hierarchy'. + * + *

                              + *

                              + * + * @generated + */ +public class EInterfaceHierarchyImpl extends EGraphImpl implements EInterfaceHierarchy { + /** + * + * + * @generated + */ + protected EInterfaceHierarchyImpl() { + super(); + } + + /** + * + * + * @generated + */ + protected EClass eStaticClass() { + return JavaPackage.Literals.EINTERFACE_HIERARCHY; + } + +} //EInterfaceHierarchyImpl \ No newline at end of file diff --git a/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/impl/EJavaClassImpl.java b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/impl/EJavaClassImpl.java new file mode 100644 index 000000000..5e2b88ab1 --- /dev/null +++ b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/impl/EJavaClassImpl.java @@ -0,0 +1,221 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java.impl; + +import com.ibm.wala.ecore.common.impl.EObjectWithContainerIdImpl; + +import com.ibm.wala.ecore.java.EClassLoaderName; +import com.ibm.wala.ecore.java.EJavaClass; +import com.ibm.wala.ecore.java.JavaPackage; + +import org.eclipse.emf.common.notify.Notification; + +import org.eclipse.emf.ecore.EClass; + +import org.eclipse.emf.ecore.impl.ENotificationImpl; + +/** + * + * An implementation of the model object 'EJava Class'. + * + *

                              + * The following features are implemented: + *

                                + *
                              • {@link com.ibm.wala.ecore.java.impl.EJavaClassImpl#getClassName Class Name}
                              • + *
                              • {@link com.ibm.wala.ecore.java.impl.EJavaClassImpl#getLoader Loader}
                              • + *
                              + *

                              + * + * @generated + */ +public class EJavaClassImpl extends EObjectWithContainerIdImpl implements EJavaClass { + /** + * The default value of the '{@link #getClassName() Class Name}' attribute. + * + * + * @see #getClassName() + * @generated + * @ordered + */ + protected static final String CLASS_NAME_EDEFAULT = null; + + /** + * The cached value of the '{@link #getClassName() Class Name}' attribute. + * + * + * @see #getClassName() + * @generated + * @ordered + */ + protected String className = CLASS_NAME_EDEFAULT; + + /** + * The default value of the '{@link #getLoader() Loader}' attribute. + * + * + * @see #getLoader() + * @generated + * @ordered + */ + protected static final EClassLoaderName LOADER_EDEFAULT = EClassLoaderName.APPLICATION_LITERAL; + + /** + * The cached value of the '{@link #getLoader() Loader}' attribute. + * + * + * @see #getLoader() + * @generated + * @ordered + */ + protected EClassLoaderName loader = LOADER_EDEFAULT; + + /** + * + * + * @generated + */ + protected EJavaClassImpl() { + super(); + } + + /** + * + * + * @generated + */ + protected EClass eStaticClass() { + return JavaPackage.Literals.EJAVA_CLASS; + } + + /** + * + * + * @generated + */ + public String getClassName() { + return className; + } + + /** + * + * + * @generated + */ + public void setClassName(String newClassName) { + String oldClassName = className; + className = newClassName; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, JavaPackage.EJAVA_CLASS__CLASS_NAME, oldClassName, className)); + } + + /** + * + * + * @generated + */ + public EClassLoaderName getLoader() { + return loader; + } + + /** + * + * + * @generated + */ + public void setLoader(EClassLoaderName newLoader) { + EClassLoaderName oldLoader = loader; + loader = newLoader == null ? LOADER_EDEFAULT : newLoader; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, JavaPackage.EJAVA_CLASS__LOADER, oldLoader, loader)); + } + + /** + * + * + * @generated + */ + public Object eGet(int featureID, boolean resolve, boolean coreType) { + switch (featureID) { + case JavaPackage.EJAVA_CLASS__CLASS_NAME: + return getClassName(); + case JavaPackage.EJAVA_CLASS__LOADER: + return getLoader(); + } + return super.eGet(featureID, resolve, coreType); + } + + /** + * + * + * @generated + */ + public void eSet(int featureID, Object newValue) { + switch (featureID) { + case JavaPackage.EJAVA_CLASS__CLASS_NAME: + setClassName((String)newValue); + return; + case JavaPackage.EJAVA_CLASS__LOADER: + setLoader((EClassLoaderName)newValue); + return; + } + super.eSet(featureID, newValue); + } + + /** + * + * + * @generated + */ + public void eUnset(int featureID) { + switch (featureID) { + case JavaPackage.EJAVA_CLASS__CLASS_NAME: + setClassName(CLASS_NAME_EDEFAULT); + return; + case JavaPackage.EJAVA_CLASS__LOADER: + setLoader(LOADER_EDEFAULT); + return; + } + super.eUnset(featureID); + } + + /** + * + * + * @generated + */ + public boolean eIsSet(int featureID) { + switch (featureID) { + case JavaPackage.EJAVA_CLASS__CLASS_NAME: + return CLASS_NAME_EDEFAULT == null ? className != null : !CLASS_NAME_EDEFAULT.equals(className); + case JavaPackage.EJAVA_CLASS__LOADER: + return loader != LOADER_EDEFAULT; + } + return super.eIsSet(featureID); + } + + /** + * + * + */ + public String toString() { + return className; + } + + public boolean equals(Object obj) { + if (getClass().equals(obj.getClass())) { + EJavaClassImpl other = (EJavaClassImpl)obj; + return loader.equals(other.loader) && className.equals(other.className); + } else { + return false; + } + } + + public int hashCode() { + return loader.hashCode() + 93 * className.hashCode(); + } + +} //EJavaClassImpl \ No newline at end of file diff --git a/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/impl/EJavaMethodImpl.java b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/impl/EJavaMethodImpl.java new file mode 100644 index 000000000..239144109 --- /dev/null +++ b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/impl/EJavaMethodImpl.java @@ -0,0 +1,330 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java.impl; + +import com.ibm.wala.ecore.common.impl.EObjectWithContainerIdImpl; + +import com.ibm.wala.ecore.java.EJavaClass; +import com.ibm.wala.ecore.java.EJavaMethod; +import com.ibm.wala.ecore.java.JavaPackage; + +import org.eclipse.emf.common.notify.Notification; + +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.InternalEObject; + +import org.eclipse.emf.ecore.impl.ENotificationImpl; + +/** + * + * An implementation of the model object 'EJava Method'. + * + *

                              + * The following features are implemented: + *

                                + *
                              • {@link com.ibm.wala.ecore.java.impl.EJavaMethodImpl#getMethodName Method Name}
                              • + *
                              • {@link com.ibm.wala.ecore.java.impl.EJavaMethodImpl#getDescriptor Descriptor}
                              • + *
                              • {@link com.ibm.wala.ecore.java.impl.EJavaMethodImpl#getJavaClass Java Class}
                              • + *
                              • {@link com.ibm.wala.ecore.java.impl.EJavaMethodImpl#getSignature Signature}
                              • + *
                              + *

                              + * + * @generated + */ +public class EJavaMethodImpl extends EObjectWithContainerIdImpl implements EJavaMethod { + + + /** + * The default value of the '{@link #getMethodName() Method Name}' attribute. + * + * + * @see #getMethodName() + * @generated + * @ordered + */ + protected static final String METHOD_NAME_EDEFAULT = null; + + /** + * The cached value of the '{@link #getMethodName() Method Name}' attribute. + * + * + * @see #getMethodName() + * @generated + * @ordered + */ + protected String methodName = METHOD_NAME_EDEFAULT; + + /** + * The default value of the '{@link #getDescriptor() Descriptor}' attribute. + * + * + * @see #getDescriptor() + * @generated + * @ordered + */ + protected static final String DESCRIPTOR_EDEFAULT = null; + + /** + * The cached value of the '{@link #getDescriptor() Descriptor}' attribute. + * + * + * @see #getDescriptor() + * @generated + * @ordered + */ + protected String descriptor = DESCRIPTOR_EDEFAULT; + + /** + * The cached value of the '{@link #getJavaClass() Java Class}' reference. + * + * + * @see #getJavaClass() + * @generated + * @ordered + */ + protected EJavaClass javaClass = null; + + /** + * The default value of the '{@link #getSignature() Signature}' attribute. + * + * + * @see #getSignature() + * @generated + * @ordered + */ + protected static final String SIGNATURE_EDEFAULT = null; + + /** + * + * + * @generated + */ + protected EJavaMethodImpl() { + super(); + } + + /** + * + * + * @generated + */ + protected EClass eStaticClass() { + return JavaPackage.Literals.EJAVA_METHOD; + } + + /** + * + * + * @generated + */ + public String getMethodName() { + return methodName; + } + + /** + * + * + * @generated + */ + public void setMethodName(String newMethodName) { + String oldMethodName = methodName; + methodName = newMethodName; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, JavaPackage.EJAVA_METHOD__METHOD_NAME, oldMethodName, methodName)); + } + + /** + * + * + * @generated + */ + public String getDescriptor() { + return descriptor; + } + + /** + * + * + * @generated + */ + public void setDescriptor(String newDescriptor) { + String oldDescriptor = descriptor; + descriptor = newDescriptor; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, JavaPackage.EJAVA_METHOD__DESCRIPTOR, oldDescriptor, descriptor)); + } + + /** + * + * + * @generated + */ + public EJavaClass getJavaClass() { + if (javaClass != null && javaClass.eIsProxy()) { + InternalEObject oldJavaClass = (InternalEObject)javaClass; + javaClass = (EJavaClass)eResolveProxy(oldJavaClass); + if (javaClass != oldJavaClass) { + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.RESOLVE, JavaPackage.EJAVA_METHOD__JAVA_CLASS, oldJavaClass, javaClass)); + } + } + return javaClass; + } + + /** + * + * + * @generated + */ + public EJavaClass basicGetJavaClass() { + return javaClass; + } + + /** + * + * + * @generated + */ + public void setJavaClass(EJavaClass newJavaClass) { + EJavaClass oldJavaClass = javaClass; + javaClass = newJavaClass; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, JavaPackage.EJAVA_METHOD__JAVA_CLASS, oldJavaClass, javaClass)); + } + + /** + * + * + * @generated + */ + public String getSignature() { + // TODO: implement this method to return the 'Signature' attribute + // Ensure that you remove @generated or mark it @generated NOT + throw new UnsupportedOperationException(); + } + + /** + * + * + * @generated + */ + public boolean isClinit() { + // TODO: implement this method + // Ensure that you remove @generated or mark it @generated NOT + throw new UnsupportedOperationException(); + } + + /** + * + * + * @generated + */ + public Object eGet(int featureID, boolean resolve, boolean coreType) { + switch (featureID) { + case JavaPackage.EJAVA_METHOD__METHOD_NAME: + return getMethodName(); + case JavaPackage.EJAVA_METHOD__DESCRIPTOR: + return getDescriptor(); + case JavaPackage.EJAVA_METHOD__JAVA_CLASS: + if (resolve) return getJavaClass(); + return basicGetJavaClass(); + case JavaPackage.EJAVA_METHOD__SIGNATURE: + return getSignature(); + } + return super.eGet(featureID, resolve, coreType); + } + + /** + * + * + * @generated + */ + public void eSet(int featureID, Object newValue) { + switch (featureID) { + case JavaPackage.EJAVA_METHOD__METHOD_NAME: + setMethodName((String)newValue); + return; + case JavaPackage.EJAVA_METHOD__DESCRIPTOR: + setDescriptor((String)newValue); + return; + case JavaPackage.EJAVA_METHOD__JAVA_CLASS: + setJavaClass((EJavaClass)newValue); + return; + } + super.eSet(featureID, newValue); + } + + /** + * + * + * @generated + */ + public void eUnset(int featureID) { + switch (featureID) { + case JavaPackage.EJAVA_METHOD__METHOD_NAME: + setMethodName(METHOD_NAME_EDEFAULT); + return; + case JavaPackage.EJAVA_METHOD__DESCRIPTOR: + setDescriptor(DESCRIPTOR_EDEFAULT); + return; + case JavaPackage.EJAVA_METHOD__JAVA_CLASS: + setJavaClass((EJavaClass)null); + return; + } + super.eUnset(featureID); + } + + /** + * + * + * @generated + */ + public boolean eIsSet(int featureID) { + switch (featureID) { + case JavaPackage.EJAVA_METHOD__METHOD_NAME: + return METHOD_NAME_EDEFAULT == null ? methodName != null : !METHOD_NAME_EDEFAULT.equals(methodName); + case JavaPackage.EJAVA_METHOD__DESCRIPTOR: + return DESCRIPTOR_EDEFAULT == null ? descriptor != null : !DESCRIPTOR_EDEFAULT.equals(descriptor); + case JavaPackage.EJAVA_METHOD__JAVA_CLASS: + return javaClass != null; + case JavaPackage.EJAVA_METHOD__SIGNATURE: + return SIGNATURE_EDEFAULT == null ? getSignature() != null : !SIGNATURE_EDEFAULT.equals(getSignature()); + } + return super.eIsSet(featureID); + } + + /** + * + * + * @generated + */ + public String toString() { + if (eIsProxy()) return super.toString(); + + StringBuffer result = new StringBuffer(super.toString()); + result.append(" (methodName: "); + result.append(methodName); + result.append(", descriptor: "); + result.append(descriptor); + result.append(')'); + return result.toString(); + } + + public boolean equals(Object obj) { + if (getClass().equals(obj.getClass())) { + EJavaMethodImpl other = (EJavaMethodImpl)obj; + return descriptor.equals(other.descriptor) && javaClass.equals(other.javaClass) && methodName.equals(other.methodName); + } else { + return false; + } + } + + public int hashCode() { + return descriptor.hashCode() + 157 * javaClass.hashCode() + 1439 * methodName.hashCode(); + } + +} //EJavaMethodImpl \ No newline at end of file diff --git a/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/impl/ETypeHierarchyImpl.java b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/impl/ETypeHierarchyImpl.java new file mode 100644 index 000000000..780bb023b --- /dev/null +++ b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/impl/ETypeHierarchyImpl.java @@ -0,0 +1,309 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java.impl; + +import com.ibm.wala.ecore.common.ERelation; + +import com.ibm.wala.ecore.java.EClassHierarchy; +import com.ibm.wala.ecore.java.EInterfaceHierarchy; +import com.ibm.wala.ecore.java.ETypeHierarchy; +import com.ibm.wala.ecore.java.JavaPackage; + +import org.eclipse.emf.common.notify.Notification; +import org.eclipse.emf.common.notify.NotificationChain; + +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.InternalEObject; + +import org.eclipse.emf.ecore.impl.ENotificationImpl; +import org.eclipse.emf.ecore.impl.EObjectImpl; + +/** + * + * An implementation of the model object 'EType Hierarchy'. + * + *

                              + * The following features are implemented: + *

                                + *
                              • {@link com.ibm.wala.ecore.java.impl.ETypeHierarchyImpl#getClasses Classes}
                              • + *
                              • {@link com.ibm.wala.ecore.java.impl.ETypeHierarchyImpl#getInterfaces Interfaces}
                              • + *
                              • {@link com.ibm.wala.ecore.java.impl.ETypeHierarchyImpl#getImplements Implements}
                              • + *
                              + *

                              + * + * @generated + */ +public class ETypeHierarchyImpl extends EObjectImpl implements ETypeHierarchy { + /** + * The cached value of the '{@link #getClasses() Classes}' containment reference. + * + * + * @see #getClasses() + * @generated + * @ordered + */ + protected EClassHierarchy classes = null; + + /** + * The cached value of the '{@link #getInterfaces() Interfaces}' containment reference. + * + * + * @see #getInterfaces() + * @generated + * @ordered + */ + protected EInterfaceHierarchy interfaces = null; + + /** + * The cached value of the '{@link #getImplements() Implements}' containment reference. + * + * + * @see #getImplements() + * @generated + * @ordered + */ + protected ERelation implements_ = null; + + /** + * + * + * @generated + */ + protected ETypeHierarchyImpl() { + super(); + } + + /** + * + * + * @generated + */ + protected EClass eStaticClass() { + return JavaPackage.Literals.ETYPE_HIERARCHY; + } + + /** + * + * + * @generated + */ + public EClassHierarchy getClasses() { + return classes; + } + + /** + * + * + * @generated + */ + public NotificationChain basicSetClasses(EClassHierarchy newClasses, NotificationChain msgs) { + EClassHierarchy oldClasses = classes; + classes = newClasses; + if (eNotificationRequired()) { + ENotificationImpl notification = new ENotificationImpl(this, Notification.SET, JavaPackage.ETYPE_HIERARCHY__CLASSES, oldClasses, newClasses); + if (msgs == null) msgs = notification; else msgs.add(notification); + } + return msgs; + } + + /** + * + * + * @generated + */ + public void setClasses(EClassHierarchy newClasses) { + if (newClasses != classes) { + NotificationChain msgs = null; + if (classes != null) + msgs = ((InternalEObject)classes).eInverseRemove(this, EOPPOSITE_FEATURE_BASE - JavaPackage.ETYPE_HIERARCHY__CLASSES, null, msgs); + if (newClasses != null) + msgs = ((InternalEObject)newClasses).eInverseAdd(this, EOPPOSITE_FEATURE_BASE - JavaPackage.ETYPE_HIERARCHY__CLASSES, null, msgs); + msgs = basicSetClasses(newClasses, msgs); + if (msgs != null) msgs.dispatch(); + } + else if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, JavaPackage.ETYPE_HIERARCHY__CLASSES, newClasses, newClasses)); + } + + /** + * + * + * @generated + */ + public EInterfaceHierarchy getInterfaces() { + return interfaces; + } + + /** + * + * + * @generated + */ + public NotificationChain basicSetInterfaces(EInterfaceHierarchy newInterfaces, NotificationChain msgs) { + EInterfaceHierarchy oldInterfaces = interfaces; + interfaces = newInterfaces; + if (eNotificationRequired()) { + ENotificationImpl notification = new ENotificationImpl(this, Notification.SET, JavaPackage.ETYPE_HIERARCHY__INTERFACES, oldInterfaces, newInterfaces); + if (msgs == null) msgs = notification; else msgs.add(notification); + } + return msgs; + } + + /** + * + * + * @generated + */ + public void setInterfaces(EInterfaceHierarchy newInterfaces) { + if (newInterfaces != interfaces) { + NotificationChain msgs = null; + if (interfaces != null) + msgs = ((InternalEObject)interfaces).eInverseRemove(this, EOPPOSITE_FEATURE_BASE - JavaPackage.ETYPE_HIERARCHY__INTERFACES, null, msgs); + if (newInterfaces != null) + msgs = ((InternalEObject)newInterfaces).eInverseAdd(this, EOPPOSITE_FEATURE_BASE - JavaPackage.ETYPE_HIERARCHY__INTERFACES, null, msgs); + msgs = basicSetInterfaces(newInterfaces, msgs); + if (msgs != null) msgs.dispatch(); + } + else if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, JavaPackage.ETYPE_HIERARCHY__INTERFACES, newInterfaces, newInterfaces)); + } + + /** + * + * + * @generated + */ + public ERelation getImplements() { + return implements_; + } + + /** + * + * + * @generated + */ + public NotificationChain basicSetImplements(ERelation newImplements, NotificationChain msgs) { + ERelation oldImplements = implements_; + implements_ = newImplements; + if (eNotificationRequired()) { + ENotificationImpl notification = new ENotificationImpl(this, Notification.SET, JavaPackage.ETYPE_HIERARCHY__IMPLEMENTS, oldImplements, newImplements); + if (msgs == null) msgs = notification; else msgs.add(notification); + } + return msgs; + } + + /** + * + * + * @generated + */ + public void setImplements(ERelation newImplements) { + if (newImplements != implements_) { + NotificationChain msgs = null; + if (implements_ != null) + msgs = ((InternalEObject)implements_).eInverseRemove(this, EOPPOSITE_FEATURE_BASE - JavaPackage.ETYPE_HIERARCHY__IMPLEMENTS, null, msgs); + if (newImplements != null) + msgs = ((InternalEObject)newImplements).eInverseAdd(this, EOPPOSITE_FEATURE_BASE - JavaPackage.ETYPE_HIERARCHY__IMPLEMENTS, null, msgs); + msgs = basicSetImplements(newImplements, msgs); + if (msgs != null) msgs.dispatch(); + } + else if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, JavaPackage.ETYPE_HIERARCHY__IMPLEMENTS, newImplements, newImplements)); + } + + /** + * + * + * @generated + */ + public NotificationChain eInverseRemove(InternalEObject otherEnd, int featureID, NotificationChain msgs) { + switch (featureID) { + case JavaPackage.ETYPE_HIERARCHY__CLASSES: + return basicSetClasses(null, msgs); + case JavaPackage.ETYPE_HIERARCHY__INTERFACES: + return basicSetInterfaces(null, msgs); + case JavaPackage.ETYPE_HIERARCHY__IMPLEMENTS: + return basicSetImplements(null, msgs); + } + return super.eInverseRemove(otherEnd, featureID, msgs); + } + + /** + * + * + * @generated + */ + public Object eGet(int featureID, boolean resolve, boolean coreType) { + switch (featureID) { + case JavaPackage.ETYPE_HIERARCHY__CLASSES: + return getClasses(); + case JavaPackage.ETYPE_HIERARCHY__INTERFACES: + return getInterfaces(); + case JavaPackage.ETYPE_HIERARCHY__IMPLEMENTS: + return getImplements(); + } + return super.eGet(featureID, resolve, coreType); + } + + /** + * + * + * @generated + */ + public void eSet(int featureID, Object newValue) { + switch (featureID) { + case JavaPackage.ETYPE_HIERARCHY__CLASSES: + setClasses((EClassHierarchy)newValue); + return; + case JavaPackage.ETYPE_HIERARCHY__INTERFACES: + setInterfaces((EInterfaceHierarchy)newValue); + return; + case JavaPackage.ETYPE_HIERARCHY__IMPLEMENTS: + setImplements((ERelation)newValue); + return; + } + super.eSet(featureID, newValue); + } + + /** + * + * + * @generated + */ + public void eUnset(int featureID) { + switch (featureID) { + case JavaPackage.ETYPE_HIERARCHY__CLASSES: + setClasses((EClassHierarchy)null); + return; + case JavaPackage.ETYPE_HIERARCHY__INTERFACES: + setInterfaces((EInterfaceHierarchy)null); + return; + case JavaPackage.ETYPE_HIERARCHY__IMPLEMENTS: + setImplements((ERelation)null); + return; + } + super.eUnset(featureID); + } + + /** + * + * + * @generated + */ + public boolean eIsSet(int featureID) { + switch (featureID) { + case JavaPackage.ETYPE_HIERARCHY__CLASSES: + return classes != null; + case JavaPackage.ETYPE_HIERARCHY__INTERFACES: + return interfaces != null; + case JavaPackage.ETYPE_HIERARCHY__IMPLEMENTS: + return implements_ != null; + } + return super.eIsSet(featureID); + } + +} //ETypeHierarchyImpl \ No newline at end of file diff --git a/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/impl/JavaFactoryImpl.java b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/impl/JavaFactoryImpl.java new file mode 100644 index 000000000..c590f0a06 --- /dev/null +++ b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/impl/JavaFactoryImpl.java @@ -0,0 +1,201 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java.impl; + +import com.ibm.wala.ecore.java.*; + +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EDataType; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EPackage; + +import org.eclipse.emf.ecore.impl.EFactoryImpl; + +import org.eclipse.emf.ecore.plugin.EcorePlugin; + +/** + * + * An implementation of the model Factory. + * + * @generated + */ +public class JavaFactoryImpl extends EFactoryImpl implements JavaFactory { + /** + * Creates the default factory implementation. + * + * + * @generated + */ + public static JavaFactory init() { + try { + JavaFactory theJavaFactory = (JavaFactory)EPackage.Registry.INSTANCE.getEFactory("http:///com/ibm/wala/wala.ecore.java"); + if (theJavaFactory != null) { + return theJavaFactory; + } + } + catch (Exception exception) { + EcorePlugin.INSTANCE.log(exception); + } + return new JavaFactoryImpl(); + } + + /** + * Creates an instance of the factory. + * + * + * @generated + */ + public JavaFactoryImpl() { + super(); + } + + /** + * + * + * @generated + */ + public EObject create(EClass eClass) { + switch (eClass.getClassifierID()) { + case JavaPackage.EJAVA_CLASS: return createEJavaClass(); + case JavaPackage.EJAVA_METHOD: return createEJavaMethod(); + case JavaPackage.ECALL_SITE: return createECallSite(); + case JavaPackage.ECLASS_HIERARCHY: return createEClassHierarchy(); + case JavaPackage.EINTERFACE_HIERARCHY: return createEInterfaceHierarchy(); + case JavaPackage.ETYPE_HIERARCHY: return createETypeHierarchy(); + default: + throw new IllegalArgumentException("The class '" + eClass.getName() + "' is not a valid classifier"); + } + } + + /** + * + * + * @generated + */ + public Object createFromString(EDataType eDataType, String initialValue) { + switch (eDataType.getClassifierID()) { + case JavaPackage.ECLASS_LOADER_NAME: + return createEClassLoaderNameFromString(eDataType, initialValue); + default: + throw new IllegalArgumentException("The datatype '" + eDataType.getName() + "' is not a valid classifier"); + } + } + + /** + * + * + * @generated + */ + public String convertToString(EDataType eDataType, Object instanceValue) { + switch (eDataType.getClassifierID()) { + case JavaPackage.ECLASS_LOADER_NAME: + return convertEClassLoaderNameToString(eDataType, instanceValue); + default: + throw new IllegalArgumentException("The datatype '" + eDataType.getName() + "' is not a valid classifier"); + } + } + + /** + * + * + * @generated + */ + public EJavaClass createEJavaClass() { + EJavaClassImpl eJavaClass = new EJavaClassImpl(); + return eJavaClass; + } + + /** + * + * + * @generated + */ + public EJavaMethod createEJavaMethod() { + EJavaMethodImpl eJavaMethod = new EJavaMethodImpl(); + return eJavaMethod; + } + + /** + * + * + * @generated + */ + public ECallSite createECallSite() { + ECallSiteImpl eCallSite = new ECallSiteImpl(); + return eCallSite; + } + + /** + * + * + * @generated + */ + public EClassHierarchy createEClassHierarchy() { + EClassHierarchyImpl eClassHierarchy = new EClassHierarchyImpl(); + return eClassHierarchy; + } + + /** + * + * + * @generated + */ + public EInterfaceHierarchy createEInterfaceHierarchy() { + EInterfaceHierarchyImpl eInterfaceHierarchy = new EInterfaceHierarchyImpl(); + return eInterfaceHierarchy; + } + + /** + * + * + * @generated + */ + public ETypeHierarchy createETypeHierarchy() { + ETypeHierarchyImpl eTypeHierarchy = new ETypeHierarchyImpl(); + return eTypeHierarchy; + } + + /** + * + * + * @generated + */ + public EClassLoaderName createEClassLoaderNameFromString(EDataType eDataType, String initialValue) { + EClassLoaderName result = EClassLoaderName.get(initialValue); + if (result == null) throw new IllegalArgumentException("The value '" + initialValue + "' is not a valid enumerator of '" + eDataType.getName() + "'"); + return result; + } + + /** + * + * + * @generated + */ + public String convertEClassLoaderNameToString(EDataType eDataType, Object instanceValue) { + return instanceValue == null ? null : instanceValue.toString(); + } + + /** + * + * + * @generated + */ + public JavaPackage getJavaPackage() { + return (JavaPackage)getEPackage(); + } + + /** + * + * + * @deprecated + * @generated + */ + public static JavaPackage getPackage() { + return JavaPackage.eINSTANCE; + } + +} //JavaFactoryImpl diff --git a/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/impl/JavaPackageImpl.java b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/impl/JavaPackageImpl.java new file mode 100644 index 000000000..979671bd5 --- /dev/null +++ b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/impl/JavaPackageImpl.java @@ -0,0 +1,515 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java.impl; + +import com.ibm.wala.ecore.common.CommonPackage; + +import com.ibm.wala.ecore.common.impl.CommonPackageImpl; + +import com.ibm.wala.ecore.graph.GraphPackage; + +import com.ibm.wala.ecore.graph.impl.GraphPackageImpl; + +import com.ibm.wala.ecore.j2ee.scope.J2EEScopePackage; + +import com.ibm.wala.ecore.j2ee.scope.impl.J2EEScopePackageImpl; + +import com.ibm.wala.ecore.java.ECallSite; +import com.ibm.wala.ecore.java.EClassHierarchy; +import com.ibm.wala.ecore.java.EClassLoaderName; +import com.ibm.wala.ecore.java.EInterfaceHierarchy; +import com.ibm.wala.ecore.java.EJavaClass; +import com.ibm.wala.ecore.java.EJavaMethod; +import com.ibm.wala.ecore.java.ETypeHierarchy; +import com.ibm.wala.ecore.java.JavaFactory; +import com.ibm.wala.ecore.java.JavaPackage; + +import com.ibm.wala.ecore.java.callGraph.CallGraphPackage; + +import com.ibm.wala.ecore.java.callGraph.impl.CallGraphPackageImpl; + +import com.ibm.wala.ecore.java.pointerAnalysis.PointerAnalysisPackage; + +import com.ibm.wala.ecore.java.pointerAnalysis.impl.PointerAnalysisPackageImpl; + +import com.ibm.wala.ecore.java.scope.JavaScopePackage; + +import com.ibm.wala.ecore.java.scope.impl.JavaScopePackageImpl; + +import com.ibm.wala.ecore.perf.PerfPackage; + +import com.ibm.wala.ecore.perf.impl.PerfPackageImpl; + +import com.ibm.wala.ecore.regex.RegexPackage; + +import com.ibm.wala.ecore.regex.impl.RegexPackageImpl; + +import org.eclipse.emf.ecore.EAttribute; +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EEnum; +import org.eclipse.emf.ecore.EPackage; +import org.eclipse.emf.ecore.EReference; + +import org.eclipse.emf.ecore.impl.EPackageImpl; + +/** + * + * An implementation of the model Package. + * + * @generated + */ +public class JavaPackageImpl extends EPackageImpl implements JavaPackage { + /** + * + * + * @generated + */ + private EClass eJavaClassEClass = null; + + /** + * + * + * @generated + */ + private EClass eJavaMethodEClass = null; + + /** + * + * + * @generated + */ + private EClass eCallSiteEClass = null; + + /** + * + * + * @generated + */ + private EClass eClassHierarchyEClass = null; + + /** + * + * + * @generated + */ + private EClass eInterfaceHierarchyEClass = null; + + /** + * + * + * @generated + */ + private EClass eTypeHierarchyEClass = null; + + /** + * + * + * @generated + */ + private EEnum eClassLoaderNameEEnum = null; + + /** + * Creates an instance of the model Package, registered with + * {@link org.eclipse.emf.ecore.EPackage.Registry EPackage.Registry} by the package + * package URI value. + *

                              Note: the correct way to create the package is via the static + * factory method {@link #init init()}, which also performs + * initialization of the package, or returns the registered package, + * if one already exists. + * + * + * @see org.eclipse.emf.ecore.EPackage.Registry + * @see com.ibm.wala.ecore.java.JavaPackage#eNS_URI + * @see #init() + * @generated + */ + private JavaPackageImpl() { + super(eNS_URI, JavaFactory.eINSTANCE); + } + + /** + * + * + * @generated + */ + private static boolean isInited = false; + + /** + * Creates, registers, and initializes the Package for this + * model, and for any others upon which it depends. Simple + * dependencies are satisfied by calling this method on all + * dependent packages before doing anything else. This method drives + * initialization for interdependent packages directly, in parallel + * with this package, itself. + *

                              Of this package and its interdependencies, all packages which + * have not yet been registered by their URI values are first created + * and registered. The packages are then initialized in two steps: + * meta-model objects for all of the packages are created before any + * are initialized, since one package's meta-model objects may refer to + * those of another. + *

                              Invocation of this method will not affect any packages that have + * already been initialized. + * + * + * @see #eNS_URI + * @see #createPackageContents() + * @see #initializePackageContents() + * @generated + */ + public static JavaPackage init() { + if (isInited) return (JavaPackage)EPackage.Registry.INSTANCE.getEPackage(JavaPackage.eNS_URI); + + // Obtain or create and register package + JavaPackageImpl theJavaPackage = (JavaPackageImpl)(EPackage.Registry.INSTANCE.getEPackage(eNS_URI) instanceof JavaPackageImpl ? EPackage.Registry.INSTANCE.getEPackage(eNS_URI) : new JavaPackageImpl()); + + isInited = true; + + // Obtain or create and register interdependencies + GraphPackageImpl theGraphPackage = (GraphPackageImpl)(EPackage.Registry.INSTANCE.getEPackage(GraphPackage.eNS_URI) instanceof GraphPackageImpl ? EPackage.Registry.INSTANCE.getEPackage(GraphPackage.eNS_URI) : GraphPackage.eINSTANCE); + CommonPackageImpl theCommonPackage = (CommonPackageImpl)(EPackage.Registry.INSTANCE.getEPackage(CommonPackage.eNS_URI) instanceof CommonPackageImpl ? EPackage.Registry.INSTANCE.getEPackage(CommonPackage.eNS_URI) : CommonPackage.eINSTANCE); + RegexPackageImpl theRegexPackage = (RegexPackageImpl)(EPackage.Registry.INSTANCE.getEPackage(RegexPackage.eNS_URI) instanceof RegexPackageImpl ? EPackage.Registry.INSTANCE.getEPackage(RegexPackage.eNS_URI) : RegexPackage.eINSTANCE); + PerfPackageImpl thePerfPackage = (PerfPackageImpl)(EPackage.Registry.INSTANCE.getEPackage(PerfPackage.eNS_URI) instanceof PerfPackageImpl ? EPackage.Registry.INSTANCE.getEPackage(PerfPackage.eNS_URI) : PerfPackage.eINSTANCE); + CallGraphPackageImpl theCallGraphPackage = (CallGraphPackageImpl)(EPackage.Registry.INSTANCE.getEPackage(CallGraphPackage.eNS_URI) instanceof CallGraphPackageImpl ? EPackage.Registry.INSTANCE.getEPackage(CallGraphPackage.eNS_URI) : CallGraphPackage.eINSTANCE); + PointerAnalysisPackageImpl thePointerAnalysisPackage = (PointerAnalysisPackageImpl)(EPackage.Registry.INSTANCE.getEPackage(PointerAnalysisPackage.eNS_URI) instanceof PointerAnalysisPackageImpl ? EPackage.Registry.INSTANCE.getEPackage(PointerAnalysisPackage.eNS_URI) : PointerAnalysisPackage.eINSTANCE); + JavaScopePackageImpl theJavaScopePackage = (JavaScopePackageImpl)(EPackage.Registry.INSTANCE.getEPackage(JavaScopePackage.eNS_URI) instanceof JavaScopePackageImpl ? EPackage.Registry.INSTANCE.getEPackage(JavaScopePackage.eNS_URI) : JavaScopePackage.eINSTANCE); + J2EEScopePackageImpl theJ2EEScopePackage = (J2EEScopePackageImpl)(EPackage.Registry.INSTANCE.getEPackage(J2EEScopePackage.eNS_URI) instanceof J2EEScopePackageImpl ? EPackage.Registry.INSTANCE.getEPackage(J2EEScopePackage.eNS_URI) : J2EEScopePackage.eINSTANCE); + + // Create package meta-data objects + theJavaPackage.createPackageContents(); + theGraphPackage.createPackageContents(); + theCommonPackage.createPackageContents(); + theRegexPackage.createPackageContents(); + thePerfPackage.createPackageContents(); + theCallGraphPackage.createPackageContents(); + thePointerAnalysisPackage.createPackageContents(); + theJavaScopePackage.createPackageContents(); + theJ2EEScopePackage.createPackageContents(); + + // Initialize created meta-data + theJavaPackage.initializePackageContents(); + theGraphPackage.initializePackageContents(); + theCommonPackage.initializePackageContents(); + theRegexPackage.initializePackageContents(); + thePerfPackage.initializePackageContents(); + theCallGraphPackage.initializePackageContents(); + thePointerAnalysisPackage.initializePackageContents(); + theJavaScopePackage.initializePackageContents(); + theJ2EEScopePackage.initializePackageContents(); + + // Mark meta-data to indicate it can't be changed + theJavaPackage.freeze(); + + return theJavaPackage; + } + + /** + * + * + * @generated + */ + public EClass getEJavaClass() { + return eJavaClassEClass; + } + + /** + * + * + * @generated + */ + public EAttribute getEJavaClass_ClassName() { + return (EAttribute)eJavaClassEClass.getEStructuralFeatures().get(0); + } + + /** + * + * + * @generated + */ + public EAttribute getEJavaClass_Loader() { + return (EAttribute)eJavaClassEClass.getEStructuralFeatures().get(1); + } + + /** + * + * + * @generated + */ + public EClass getEJavaMethod() { + return eJavaMethodEClass; + } + + /** + * + * + * @generated + */ + public EAttribute getEJavaMethod_MethodName() { + return (EAttribute)eJavaMethodEClass.getEStructuralFeatures().get(0); + } + + /** + * + * + * @generated + */ + public EAttribute getEJavaMethod_Descriptor() { + return (EAttribute)eJavaMethodEClass.getEStructuralFeatures().get(1); + } + + /** + * + * + * @generated + */ + public EReference getEJavaMethod_JavaClass() { + return (EReference)eJavaMethodEClass.getEStructuralFeatures().get(2); + } + + /** + * + * + * @generated + */ + public EAttribute getEJavaMethod_Signature() { + return (EAttribute)eJavaMethodEClass.getEStructuralFeatures().get(3); + } + + /** + * + * + * @generated + */ + public EClass getECallSite() { + return eCallSiteEClass; + } + + /** + * + * + * @generated + */ + public EAttribute getECallSite_BytecodeIndex() { + return (EAttribute)eCallSiteEClass.getEStructuralFeatures().get(0); + } + + /** + * + * + * @generated + */ + public EReference getECallSite_JavaMethod() { + return (EReference)eCallSiteEClass.getEStructuralFeatures().get(1); + } + + /** + * + * + * @generated + */ + public EReference getECallSite_DeclaredTarget() { + return (EReference)eCallSiteEClass.getEStructuralFeatures().get(2); + } + + /** + * + * + * @generated + */ + public EClass getEClassHierarchy() { + return eClassHierarchyEClass; + } + + /** + * + * + * @generated + */ + public EClass getEInterfaceHierarchy() { + return eInterfaceHierarchyEClass; + } + + /** + * + * + * @generated + */ + public EClass getETypeHierarchy() { + return eTypeHierarchyEClass; + } + + /** + * + * + * @generated + */ + public EReference getETypeHierarchy_Classes() { + return (EReference)eTypeHierarchyEClass.getEStructuralFeatures().get(0); + } + + /** + * + * + * @generated + */ + public EReference getETypeHierarchy_Interfaces() { + return (EReference)eTypeHierarchyEClass.getEStructuralFeatures().get(1); + } + + /** + * + * + * @generated + */ + public EReference getETypeHierarchy_Implements() { + return (EReference)eTypeHierarchyEClass.getEStructuralFeatures().get(2); + } + + /** + * + * + * @generated + */ + public EEnum getEClassLoaderName() { + return eClassLoaderNameEEnum; + } + + /** + * + * + * @generated + */ + public JavaFactory getJavaFactory() { + return (JavaFactory)getEFactoryInstance(); + } + + /** + * + * + * @generated + */ + private boolean isCreated = false; + + /** + * Creates the meta-model objects for the package. This method is + * guarded to have no affect on any invocation but its first. + * + * + * @generated + */ + public void createPackageContents() { + if (isCreated) return; + isCreated = true; + + // Create classes and their features + eJavaClassEClass = createEClass(EJAVA_CLASS); + createEAttribute(eJavaClassEClass, EJAVA_CLASS__CLASS_NAME); + createEAttribute(eJavaClassEClass, EJAVA_CLASS__LOADER); + + eJavaMethodEClass = createEClass(EJAVA_METHOD); + createEAttribute(eJavaMethodEClass, EJAVA_METHOD__METHOD_NAME); + createEAttribute(eJavaMethodEClass, EJAVA_METHOD__DESCRIPTOR); + createEReference(eJavaMethodEClass, EJAVA_METHOD__JAVA_CLASS); + createEAttribute(eJavaMethodEClass, EJAVA_METHOD__SIGNATURE); + + eCallSiteEClass = createEClass(ECALL_SITE); + createEAttribute(eCallSiteEClass, ECALL_SITE__BYTECODE_INDEX); + createEReference(eCallSiteEClass, ECALL_SITE__JAVA_METHOD); + createEReference(eCallSiteEClass, ECALL_SITE__DECLARED_TARGET); + + eClassHierarchyEClass = createEClass(ECLASS_HIERARCHY); + + eInterfaceHierarchyEClass = createEClass(EINTERFACE_HIERARCHY); + + eTypeHierarchyEClass = createEClass(ETYPE_HIERARCHY); + createEReference(eTypeHierarchyEClass, ETYPE_HIERARCHY__CLASSES); + createEReference(eTypeHierarchyEClass, ETYPE_HIERARCHY__INTERFACES); + createEReference(eTypeHierarchyEClass, ETYPE_HIERARCHY__IMPLEMENTS); + + // Create enums + eClassLoaderNameEEnum = createEEnum(ECLASS_LOADER_NAME); + } + + /** + * + * + * @generated + */ + private boolean isInitialized = false; + + /** + * Complete the initialization of the package and its meta-model. This + * method is guarded to have no affect on any invocation but its first. + * + * + * @generated + */ + public void initializePackageContents() { + if (isInitialized) return; + isInitialized = true; + + // Initialize package + setName(eNAME); + setNsPrefix(eNS_PREFIX); + setNsURI(eNS_URI); + + // Obtain other dependent packages + CallGraphPackage theCallGraphPackage = (CallGraphPackage)EPackage.Registry.INSTANCE.getEPackage(CallGraphPackage.eNS_URI); + PointerAnalysisPackage thePointerAnalysisPackage = (PointerAnalysisPackage)EPackage.Registry.INSTANCE.getEPackage(PointerAnalysisPackage.eNS_URI); + JavaScopePackage theJavaScopePackage = (JavaScopePackage)EPackage.Registry.INSTANCE.getEPackage(JavaScopePackage.eNS_URI); + CommonPackage theCommonPackage = (CommonPackage)EPackage.Registry.INSTANCE.getEPackage(CommonPackage.eNS_URI); + GraphPackage theGraphPackage = (GraphPackage)EPackage.Registry.INSTANCE.getEPackage(GraphPackage.eNS_URI); + + // Add subpackages + getESubpackages().add(theCallGraphPackage); + getESubpackages().add(thePointerAnalysisPackage); + getESubpackages().add(theJavaScopePackage); + + // Add supertypes to classes + eJavaClassEClass.getESuperTypes().add(theCommonPackage.getEObjectWithContainerId()); + eJavaMethodEClass.getESuperTypes().add(theCommonPackage.getEObjectWithContainerId()); + eCallSiteEClass.getESuperTypes().add(theCommonPackage.getEObjectWithContainerId()); + eClassHierarchyEClass.getESuperTypes().add(theGraphPackage.getETree()); + eInterfaceHierarchyEClass.getESuperTypes().add(theGraphPackage.getEGraph()); + + // Initialize classes and features; add operations and parameters + initEClass(eJavaClassEClass, EJavaClass.class, "EJavaClass", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); + initEAttribute(getEJavaClass_ClassName(), ecorePackage.getEString(), "className", null, 1, 1, EJavaClass.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); + initEAttribute(getEJavaClass_Loader(), this.getEClassLoaderName(), "loader", null, 1, 1, EJavaClass.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); + + initEClass(eJavaMethodEClass, EJavaMethod.class, "EJavaMethod", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); + initEAttribute(getEJavaMethod_MethodName(), ecorePackage.getEString(), "methodName", null, 1, 1, EJavaMethod.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); + initEAttribute(getEJavaMethod_Descriptor(), ecorePackage.getEString(), "descriptor", null, 1, 1, EJavaMethod.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); + initEReference(getEJavaMethod_JavaClass(), this.getEJavaClass(), null, "javaClass", null, 1, 1, EJavaMethod.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_COMPOSITE, IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); + initEAttribute(getEJavaMethod_Signature(), ecorePackage.getEString(), "signature", null, 0, 1, EJavaMethod.class, IS_TRANSIENT, IS_VOLATILE, !IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, IS_UNIQUE, IS_DERIVED, IS_ORDERED); + + addEOperation(eJavaMethodEClass, ecorePackage.getEBoolean(), "isClinit", 0, 1); + + initEClass(eCallSiteEClass, ECallSite.class, "ECallSite", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); + initEAttribute(getECallSite_BytecodeIndex(), ecorePackage.getEInt(), "bytecodeIndex", null, 0, 1, ECallSite.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); + initEReference(getECallSite_JavaMethod(), this.getEJavaMethod(), null, "javaMethod", null, 1, 1, ECallSite.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_COMPOSITE, IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); + initEReference(getECallSite_DeclaredTarget(), this.getEJavaMethod(), null, "declaredTarget", null, 1, 1, ECallSite.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_COMPOSITE, IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); + + initEClass(eClassHierarchyEClass, EClassHierarchy.class, "EClassHierarchy", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); + + initEClass(eInterfaceHierarchyEClass, EInterfaceHierarchy.class, "EInterfaceHierarchy", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); + + initEClass(eTypeHierarchyEClass, ETypeHierarchy.class, "ETypeHierarchy", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); + initEReference(getETypeHierarchy_Classes(), this.getEClassHierarchy(), null, "classes", null, 1, 1, ETypeHierarchy.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, IS_COMPOSITE, !IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); + initEReference(getETypeHierarchy_Interfaces(), this.getEInterfaceHierarchy(), null, "interfaces", null, 1, 1, ETypeHierarchy.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, IS_COMPOSITE, !IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); + initEReference(getETypeHierarchy_Implements(), theCommonPackage.getERelation(), null, "implements", null, 1, 1, ETypeHierarchy.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, IS_COMPOSITE, !IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); + + // Initialize enums and add enum literals + initEEnum(eClassLoaderNameEEnum, EClassLoaderName.class, "EClassLoaderName"); + addEEnumLiteral(eClassLoaderNameEEnum, EClassLoaderName.APPLICATION_LITERAL); + addEEnumLiteral(eClassLoaderNameEEnum, EClassLoaderName.PRIMORDIAL_LITERAL); + addEEnumLiteral(eClassLoaderNameEEnum, EClassLoaderName.EXTENSION_LITERAL); + + // Create resource + createResource(eNS_URI); + } + +} //JavaPackageImpl diff --git a/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/pointerAnalysis/EArrayContents.java b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/pointerAnalysis/EArrayContents.java new file mode 100644 index 000000000..1be7089e9 --- /dev/null +++ b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/pointerAnalysis/EArrayContents.java @@ -0,0 +1,54 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java.pointerAnalysis; + +import com.ibm.wala.ecore.java.EJavaClass; + +/** + * + * A representation of the model object 'EArray Contents'. + * + * + *

                              + * The following features are supported: + *

                                + *
                              • {@link com.ibm.wala.ecore.java.pointerAnalysis.EArrayContents#getJavaClass Java Class}
                              • + *
                              + *

                              + * + * @see com.ibm.wala.ecore.java.pointerAnalysis.PointerAnalysisPackage#getEArrayContents() + * @model + * @generated + */ +public interface EArrayContents extends EPointer { + /** + * Returns the value of the 'Java Class' reference. + * + *

                              + * If the meaning of the 'Java Class' reference isn't clear, + * there really should be more of a description here... + *

                              + * + * @return the value of the 'Java Class' reference. + * @see #setJavaClass(EJavaClass) + * @see com.ibm.wala.ecore.java.pointerAnalysis.PointerAnalysisPackage#getEArrayContents_JavaClass() + * @model required="true" + * @generated + */ + EJavaClass getJavaClass(); + + /** + * Sets the value of the '{@link com.ibm.wala.ecore.java.pointerAnalysis.EArrayContents#getJavaClass Java Class}' reference. + * + * + * @param value the new value of the 'Java Class' reference. + * @see #getJavaClass() + * @generated + */ + void setJavaClass(EJavaClass value); + +} // EArrayContents \ No newline at end of file diff --git a/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/pointerAnalysis/EHeapGraph.java b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/pointerAnalysis/EHeapGraph.java new file mode 100644 index 000000000..f78f7793d --- /dev/null +++ b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/pointerAnalysis/EHeapGraph.java @@ -0,0 +1,22 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java.pointerAnalysis; + +import com.ibm.wala.ecore.graph.EGraph; + +/** + * + * A representation of the model object 'EHeap Graph'. + * + * + * + * @see com.ibm.wala.ecore.java.pointerAnalysis.PointerAnalysisPackage#getEHeapGraph() + * @model + * @generated + */ +public interface EHeapGraph extends EGraph { +} // EHeapGraph \ No newline at end of file diff --git a/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/pointerAnalysis/EInstance.java b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/pointerAnalysis/EInstance.java new file mode 100644 index 000000000..fd4a40154 --- /dev/null +++ b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/pointerAnalysis/EInstance.java @@ -0,0 +1,22 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java.pointerAnalysis; + +import org.eclipse.emf.ecore.EObject; + +/** + * + * A representation of the model object 'EInstance'. + * + * + * + * @see com.ibm.wala.ecore.java.pointerAnalysis.PointerAnalysisPackage#getEInstance() + * @model abstract="true" + * @generated + */ +public interface EInstance extends EObject { +} // EInstance \ No newline at end of file diff --git a/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/pointerAnalysis/EInstanceField.java b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/pointerAnalysis/EInstanceField.java new file mode 100644 index 000000000..19358e6cb --- /dev/null +++ b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/pointerAnalysis/EInstanceField.java @@ -0,0 +1,53 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java.pointerAnalysis; + + +/** + * + * A representation of the model object 'EInstance Field'. + * + * + *

                              + * The following features are supported: + *

                                + *
                              • {@link com.ibm.wala.ecore.java.pointerAnalysis.EInstanceField#getFieldName Field Name}
                              • + *
                              + *

                              + * + * @see com.ibm.wala.ecore.java.pointerAnalysis.PointerAnalysisPackage#getEInstanceField() + * @model + * @generated + */ +public interface EInstanceField extends EPointer { + /** + * Returns the value of the 'Field Name' attribute. + * + *

                              + * If the meaning of the 'Field Name' attribute isn't clear, + * there really should be more of a description here... + *

                              + * + * @return the value of the 'Field Name' attribute. + * @see #setFieldName(String) + * @see com.ibm.wala.ecore.java.pointerAnalysis.PointerAnalysisPackage#getEInstanceField_FieldName() + * @model + * @generated + */ + String getFieldName(); + + /** + * Sets the value of the '{@link com.ibm.wala.ecore.java.pointerAnalysis.EInstanceField#getFieldName Field Name}' attribute. + * + * + * @param value the new value of the 'Field Name' attribute. + * @see #getFieldName() + * @generated + */ + void setFieldName(String value); + +} // EInstanceField \ No newline at end of file diff --git a/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/pointerAnalysis/EJavaClassInstance.java b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/pointerAnalysis/EJavaClassInstance.java new file mode 100644 index 000000000..2d0885148 --- /dev/null +++ b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/pointerAnalysis/EJavaClassInstance.java @@ -0,0 +1,54 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java.pointerAnalysis; + +import com.ibm.wala.ecore.java.EJavaClass; + +/** + * + * A representation of the model object 'EJava Class Instance'. + * + * + *

                              + * The following features are supported: + *

                                + *
                              • {@link com.ibm.wala.ecore.java.pointerAnalysis.EJavaClassInstance#getJavaClass Java Class}
                              • + *
                              + *

                              + * + * @see com.ibm.wala.ecore.java.pointerAnalysis.PointerAnalysisPackage#getEJavaClassInstance() + * @model + * @generated + */ +public interface EJavaClassInstance extends EInstance { + /** + * Returns the value of the 'Java Class' reference. + * + *

                              + * If the meaning of the 'Java Class' reference isn't clear, + * there really should be more of a description here... + *

                              + * + * @return the value of the 'Java Class' reference. + * @see #setJavaClass(EJavaClass) + * @see com.ibm.wala.ecore.java.pointerAnalysis.PointerAnalysisPackage#getEJavaClassInstance_JavaClass() + * @model required="true" + * @generated + */ + EJavaClass getJavaClass(); + + /** + * Sets the value of the '{@link com.ibm.wala.ecore.java.pointerAnalysis.EJavaClassInstance#getJavaClass Java Class}' reference. + * + * + * @param value the new value of the 'Java Class' reference. + * @see #getJavaClass() + * @generated + */ + void setJavaClass(EJavaClass value); + +} // EJavaClassInstance \ No newline at end of file diff --git a/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/pointerAnalysis/ELocalPointer.java b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/pointerAnalysis/ELocalPointer.java new file mode 100644 index 000000000..46e7065d6 --- /dev/null +++ b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/pointerAnalysis/ELocalPointer.java @@ -0,0 +1,81 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java.pointerAnalysis; + +import com.ibm.wala.ecore.java.EJavaMethod; + +/** + * + * A representation of the model object 'ELocal Pointer'. + * + * + *

                              + * The following features are supported: + *

                                + *
                              • {@link com.ibm.wala.ecore.java.pointerAnalysis.ELocalPointer#getValueNumber Value Number}
                              • + *
                              • {@link com.ibm.wala.ecore.java.pointerAnalysis.ELocalPointer#getJavaMethod Java Method}
                              • + *
                              + *

                              + * + * @see com.ibm.wala.ecore.java.pointerAnalysis.PointerAnalysisPackage#getELocalPointer() + * @model + * @generated + */ +public interface ELocalPointer extends EPointer { + /** + * Returns the value of the 'Value Number' attribute. + * + *

                              + * If the meaning of the 'Value Number' attribute isn't clear, + * there really should be more of a description here... + *

                              + * + * @return the value of the 'Value Number' attribute. + * @see #setValueNumber(int) + * @see com.ibm.wala.ecore.java.pointerAnalysis.PointerAnalysisPackage#getELocalPointer_ValueNumber() + * @model required="true" + * @generated + */ + int getValueNumber(); + + /** + * Sets the value of the '{@link com.ibm.wala.ecore.java.pointerAnalysis.ELocalPointer#getValueNumber Value Number}' attribute. + * + * + * @param value the new value of the 'Value Number' attribute. + * @see #getValueNumber() + * @generated + */ + void setValueNumber(int value); + + /** + * Returns the value of the 'Java Method' reference. + * + *

                              + * If the meaning of the 'Java Method' reference isn't clear, + * there really should be more of a description here... + *

                              + * + * @return the value of the 'Java Method' reference. + * @see #setJavaMethod(EJavaMethod) + * @see com.ibm.wala.ecore.java.pointerAnalysis.PointerAnalysisPackage#getELocalPointer_JavaMethod() + * @model required="true" + * @generated + */ + EJavaMethod getJavaMethod(); + + /** + * Sets the value of the '{@link com.ibm.wala.ecore.java.pointerAnalysis.ELocalPointer#getJavaMethod Java Method}' reference. + * + * + * @param value the new value of the 'Java Method' reference. + * @see #getJavaMethod() + * @generated + */ + void setJavaMethod(EJavaMethod value); + +} // ELocalPointer \ No newline at end of file diff --git a/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/pointerAnalysis/EPointer.java b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/pointerAnalysis/EPointer.java new file mode 100644 index 000000000..6d2f642b3 --- /dev/null +++ b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/pointerAnalysis/EPointer.java @@ -0,0 +1,22 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java.pointerAnalysis; + +import org.eclipse.emf.ecore.EObject; + +/** + * + * A representation of the model object 'EPointer'. + * + * + * + * @see com.ibm.wala.ecore.java.pointerAnalysis.PointerAnalysisPackage#getEPointer() + * @model abstract="true" + * @generated + */ +public interface EPointer extends EObject { +} // EPointer \ No newline at end of file diff --git a/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/pointerAnalysis/EReturnValuePointer.java b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/pointerAnalysis/EReturnValuePointer.java new file mode 100644 index 000000000..9d85d4e08 --- /dev/null +++ b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/pointerAnalysis/EReturnValuePointer.java @@ -0,0 +1,81 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java.pointerAnalysis; + +import com.ibm.wala.ecore.java.EJavaMethod; + +/** + * + * A representation of the model object 'EReturn Value Pointer'. + * + * + *

                              + * The following features are supported: + *

                                + *
                              • {@link com.ibm.wala.ecore.java.pointerAnalysis.EReturnValuePointer#isIsExceptionalReturnValue Is Exceptional Return Value}
                              • + *
                              • {@link com.ibm.wala.ecore.java.pointerAnalysis.EReturnValuePointer#getJavaMethod Java Method}
                              • + *
                              + *

                              + * + * @see com.ibm.wala.ecore.java.pointerAnalysis.PointerAnalysisPackage#getEReturnValuePointer() + * @model + * @generated + */ +public interface EReturnValuePointer extends EPointer { + /** + * Returns the value of the 'Is Exceptional Return Value' attribute. + * + *

                              + * If the meaning of the 'Is Exceptional Return Value' attribute isn't clear, + * there really should be more of a description here... + *

                              + * + * @return the value of the 'Is Exceptional Return Value' attribute. + * @see #setIsExceptionalReturnValue(boolean) + * @see com.ibm.wala.ecore.java.pointerAnalysis.PointerAnalysisPackage#getEReturnValuePointer_IsExceptionalReturnValue() + * @model + * @generated + */ + boolean isIsExceptionalReturnValue(); + + /** + * Sets the value of the '{@link com.ibm.wala.ecore.java.pointerAnalysis.EReturnValuePointer#isIsExceptionalReturnValue Is Exceptional Return Value}' attribute. + * + * + * @param value the new value of the 'Is Exceptional Return Value' attribute. + * @see #isIsExceptionalReturnValue() + * @generated + */ + void setIsExceptionalReturnValue(boolean value); + + /** + * Returns the value of the 'Java Method' reference. + * + *

                              + * If the meaning of the 'Java Method' reference isn't clear, + * there really should be more of a description here... + *

                              + * + * @return the value of the 'Java Method' reference. + * @see #setJavaMethod(EJavaMethod) + * @see com.ibm.wala.ecore.java.pointerAnalysis.PointerAnalysisPackage#getEReturnValuePointer_JavaMethod() + * @model required="true" + * @generated + */ + EJavaMethod getJavaMethod(); + + /** + * Sets the value of the '{@link com.ibm.wala.ecore.java.pointerAnalysis.EReturnValuePointer#getJavaMethod Java Method}' reference. + * + * + * @param value the new value of the 'Java Method' reference. + * @see #getJavaMethod() + * @generated + */ + void setJavaMethod(EJavaMethod value); + +} // EReturnValuePointer \ No newline at end of file diff --git a/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/pointerAnalysis/EStaticField.java b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/pointerAnalysis/EStaticField.java new file mode 100644 index 000000000..8b37b9200 --- /dev/null +++ b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/pointerAnalysis/EStaticField.java @@ -0,0 +1,53 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java.pointerAnalysis; + + +/** + * + * A representation of the model object 'EStatic Field'. + * + * + *

                              + * The following features are supported: + *

                                + *
                              • {@link com.ibm.wala.ecore.java.pointerAnalysis.EStaticField#getFieldName Field Name}
                              • + *
                              + *

                              + * + * @see com.ibm.wala.ecore.java.pointerAnalysis.PointerAnalysisPackage#getEStaticField() + * @model + * @generated + */ +public interface EStaticField extends EPointer { + /** + * Returns the value of the 'Field Name' attribute. + * + *

                              + * If the meaning of the 'Field Name' attribute isn't clear, + * there really should be more of a description here... + *

                              + * + * @return the value of the 'Field Name' attribute. + * @see #setFieldName(String) + * @see com.ibm.wala.ecore.java.pointerAnalysis.PointerAnalysisPackage#getEStaticField_FieldName() + * @model + * @generated + */ + String getFieldName(); + + /** + * Sets the value of the '{@link com.ibm.wala.ecore.java.pointerAnalysis.EStaticField#getFieldName Field Name}' attribute. + * + * + * @param value the new value of the 'Field Name' attribute. + * @see #getFieldName() + * @generated + */ + void setFieldName(String value); + +} // EStaticField \ No newline at end of file diff --git a/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/pointerAnalysis/PointerAnalysisFactory.java b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/pointerAnalysis/PointerAnalysisFactory.java new file mode 100644 index 000000000..a990e6dc2 --- /dev/null +++ b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/pointerAnalysis/PointerAnalysisFactory.java @@ -0,0 +1,100 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java.pointerAnalysis; + +import org.eclipse.emf.ecore.EFactory; + +/** + * + * The Factory for the model. + * It provides a create method for each non-abstract class of the model. + * + * @see com.ibm.wala.ecore.java.pointerAnalysis.PointerAnalysisPackage + * @generated + */ +public interface PointerAnalysisFactory extends EFactory { + /** + * The singleton instance of the factory. + * + * + * @generated + */ + PointerAnalysisFactory eINSTANCE = com.ibm.wala.ecore.java.pointerAnalysis.impl.PointerAnalysisFactoryImpl.init(); + + /** + * Returns a new object of class 'EInstance Field'. + * + * + * @return a new object of class 'EInstance Field'. + * @generated + */ + EInstanceField createEInstanceField(); + + /** + * Returns a new object of class 'EArray Contents'. + * + * + * @return a new object of class 'EArray Contents'. + * @generated + */ + EArrayContents createEArrayContents(); + + /** + * Returns a new object of class 'EStatic Field'. + * + * + * @return a new object of class 'EStatic Field'. + * @generated + */ + EStaticField createEStaticField(); + + /** + * Returns a new object of class 'ELocal Pointer'. + * + * + * @return a new object of class 'ELocal Pointer'. + * @generated + */ + ELocalPointer createELocalPointer(); + + /** + * Returns a new object of class 'EReturn Value Pointer'. + * + * + * @return a new object of class 'EReturn Value Pointer'. + * @generated + */ + EReturnValuePointer createEReturnValuePointer(); + + /** + * Returns a new object of class 'EJava Class Instance'. + * + * + * @return a new object of class 'EJava Class Instance'. + * @generated + */ + EJavaClassInstance createEJavaClassInstance(); + + /** + * Returns a new object of class 'EHeap Graph'. + * + * + * @return a new object of class 'EHeap Graph'. + * @generated + */ + EHeapGraph createEHeapGraph(); + + /** + * Returns the package supported by this factory. + * + * + * @return the package supported by this factory. + * @generated + */ + PointerAnalysisPackage getPointerAnalysisPackage(); + +} //PointerAnalysisFactory diff --git a/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/pointerAnalysis/PointerAnalysisPackage.java b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/pointerAnalysis/PointerAnalysisPackage.java new file mode 100644 index 000000000..9adffee10 --- /dev/null +++ b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/pointerAnalysis/PointerAnalysisPackage.java @@ -0,0 +1,682 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java.pointerAnalysis; + +import com.ibm.wala.ecore.graph.GraphPackage; + +import org.eclipse.emf.ecore.EAttribute; +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EPackage; +import org.eclipse.emf.ecore.EReference; + +/** + * + * The Package for the model. + * It contains accessors for the meta objects to represent + *
                                + *
                              • each class,
                              • + *
                              • each feature of each class,
                              • + *
                              • each enum,
                              • + *
                              • and each data type
                              • + *
                              + * + * @see com.ibm.wala.ecore.java.pointerAnalysis.PointerAnalysisFactory + * @model kind="package" + * @generated + */ +public interface PointerAnalysisPackage extends EPackage { + /** + * The package name. + * + * + * @generated + */ + String eNAME = "pointerAnalysis"; + + /** + * The package namespace URI. + * + * + * @generated + */ + String eNS_URI = "http:///com/ibm/wala/wala.ecore.java.pointerAnalysis"; + + /** + * The package namespace name. + * + * + * @generated + */ + String eNS_PREFIX = "com.ibm.wala.java.pointerAnalysis"; + + /** + * The singleton instance of the package. + * + * + * @generated + */ + PointerAnalysisPackage eINSTANCE = com.ibm.wala.ecore.java.pointerAnalysis.impl.PointerAnalysisPackageImpl.init(); + + /** + * The meta object id for the '{@link com.ibm.wala.ecore.java.pointerAnalysis.impl.EPointerImpl EPointer}' class. + * + * + * @see com.ibm.wala.ecore.java.pointerAnalysis.impl.EPointerImpl + * @see com.ibm.wala.ecore.java.pointerAnalysis.impl.PointerAnalysisPackageImpl#getEPointer() + * @generated + */ + int EPOINTER = 0; + + /** + * The number of structural features of the 'EPointer' class. + * + * + * @generated + * @ordered + */ + int EPOINTER_FEATURE_COUNT = 0; + + /** + * The meta object id for the '{@link com.ibm.wala.ecore.java.pointerAnalysis.impl.EInstanceFieldImpl EInstance Field}' class. + * + * + * @see com.ibm.wala.ecore.java.pointerAnalysis.impl.EInstanceFieldImpl + * @see com.ibm.wala.ecore.java.pointerAnalysis.impl.PointerAnalysisPackageImpl#getEInstanceField() + * @generated + */ + int EINSTANCE_FIELD = 1; + + /** + * The feature id for the 'Field Name' attribute. + * + * + * @generated + * @ordered + */ + int EINSTANCE_FIELD__FIELD_NAME = EPOINTER_FEATURE_COUNT + 0; + + /** + * The number of structural features of the 'EInstance Field' class. + * + * + * @generated + * @ordered + */ + int EINSTANCE_FIELD_FEATURE_COUNT = EPOINTER_FEATURE_COUNT + 1; + + /** + * The meta object id for the '{@link com.ibm.wala.ecore.java.pointerAnalysis.impl.EArrayContentsImpl EArray Contents}' class. + * + * + * @see com.ibm.wala.ecore.java.pointerAnalysis.impl.EArrayContentsImpl + * @see com.ibm.wala.ecore.java.pointerAnalysis.impl.PointerAnalysisPackageImpl#getEArrayContents() + * @generated + */ + int EARRAY_CONTENTS = 2; + + /** + * The feature id for the 'Java Class' reference. + * + * + * @generated + * @ordered + */ + int EARRAY_CONTENTS__JAVA_CLASS = EPOINTER_FEATURE_COUNT + 0; + + /** + * The number of structural features of the 'EArray Contents' class. + * + * + * @generated + * @ordered + */ + int EARRAY_CONTENTS_FEATURE_COUNT = EPOINTER_FEATURE_COUNT + 1; + + /** + * The meta object id for the '{@link com.ibm.wala.ecore.java.pointerAnalysis.impl.EStaticFieldImpl EStatic Field}' class. + * + * + * @see com.ibm.wala.ecore.java.pointerAnalysis.impl.EStaticFieldImpl + * @see com.ibm.wala.ecore.java.pointerAnalysis.impl.PointerAnalysisPackageImpl#getEStaticField() + * @generated + */ + int ESTATIC_FIELD = 3; + + /** + * The feature id for the 'Field Name' attribute. + * + * + * @generated + * @ordered + */ + int ESTATIC_FIELD__FIELD_NAME = EPOINTER_FEATURE_COUNT + 0; + + /** + * The number of structural features of the 'EStatic Field' class. + * + * + * @generated + * @ordered + */ + int ESTATIC_FIELD_FEATURE_COUNT = EPOINTER_FEATURE_COUNT + 1; + + /** + * The meta object id for the '{@link com.ibm.wala.ecore.java.pointerAnalysis.impl.ELocalPointerImpl ELocal Pointer}' class. + * + * + * @see com.ibm.wala.ecore.java.pointerAnalysis.impl.ELocalPointerImpl + * @see com.ibm.wala.ecore.java.pointerAnalysis.impl.PointerAnalysisPackageImpl#getELocalPointer() + * @generated + */ + int ELOCAL_POINTER = 4; + + /** + * The feature id for the 'Value Number' attribute. + * + * + * @generated + * @ordered + */ + int ELOCAL_POINTER__VALUE_NUMBER = EPOINTER_FEATURE_COUNT + 0; + + /** + * The feature id for the 'Java Method' reference. + * + * + * @generated + * @ordered + */ + int ELOCAL_POINTER__JAVA_METHOD = EPOINTER_FEATURE_COUNT + 1; + + /** + * The number of structural features of the 'ELocal Pointer' class. + * + * + * @generated + * @ordered + */ + int ELOCAL_POINTER_FEATURE_COUNT = EPOINTER_FEATURE_COUNT + 2; + + /** + * The meta object id for the '{@link com.ibm.wala.ecore.java.pointerAnalysis.impl.EReturnValuePointerImpl EReturn Value Pointer}' class. + * + * + * @see com.ibm.wala.ecore.java.pointerAnalysis.impl.EReturnValuePointerImpl + * @see com.ibm.wala.ecore.java.pointerAnalysis.impl.PointerAnalysisPackageImpl#getEReturnValuePointer() + * @generated + */ + int ERETURN_VALUE_POINTER = 5; + + /** + * The feature id for the 'Is Exceptional Return Value' attribute. + * + * + * @generated + * @ordered + */ + int ERETURN_VALUE_POINTER__IS_EXCEPTIONAL_RETURN_VALUE = EPOINTER_FEATURE_COUNT + 0; + + /** + * The feature id for the 'Java Method' reference. + * + * + * @generated + * @ordered + */ + int ERETURN_VALUE_POINTER__JAVA_METHOD = EPOINTER_FEATURE_COUNT + 1; + + /** + * The number of structural features of the 'EReturn Value Pointer' class. + * + * + * @generated + * @ordered + */ + int ERETURN_VALUE_POINTER_FEATURE_COUNT = EPOINTER_FEATURE_COUNT + 2; + + /** + * The meta object id for the '{@link com.ibm.wala.ecore.java.pointerAnalysis.impl.EInstanceImpl EInstance}' class. + * + * + * @see com.ibm.wala.ecore.java.pointerAnalysis.impl.EInstanceImpl + * @see com.ibm.wala.ecore.java.pointerAnalysis.impl.PointerAnalysisPackageImpl#getEInstance() + * @generated + */ + int EINSTANCE = 6; + + /** + * The number of structural features of the 'EInstance' class. + * + * + * @generated + * @ordered + */ + int EINSTANCE_FEATURE_COUNT = 0; + + /** + * The meta object id for the '{@link com.ibm.wala.ecore.java.pointerAnalysis.impl.EJavaClassInstanceImpl EJava Class Instance}' class. + * + * + * @see com.ibm.wala.ecore.java.pointerAnalysis.impl.EJavaClassInstanceImpl + * @see com.ibm.wala.ecore.java.pointerAnalysis.impl.PointerAnalysisPackageImpl#getEJavaClassInstance() + * @generated + */ + int EJAVA_CLASS_INSTANCE = 7; + + /** + * The feature id for the 'Java Class' reference. + * + * + * @generated + * @ordered + */ + int EJAVA_CLASS_INSTANCE__JAVA_CLASS = EINSTANCE_FEATURE_COUNT + 0; + + /** + * The number of structural features of the 'EJava Class Instance' class. + * + * + * @generated + * @ordered + */ + int EJAVA_CLASS_INSTANCE_FEATURE_COUNT = EINSTANCE_FEATURE_COUNT + 1; + + /** + * The meta object id for the '{@link com.ibm.wala.ecore.java.pointerAnalysis.impl.EHeapGraphImpl EHeap Graph}' class. + * + * + * @see com.ibm.wala.ecore.java.pointerAnalysis.impl.EHeapGraphImpl + * @see com.ibm.wala.ecore.java.pointerAnalysis.impl.PointerAnalysisPackageImpl#getEHeapGraph() + * @generated + */ + int EHEAP_GRAPH = 8; + + /** + * The feature id for the 'Nodes' reference. + * + * + * @generated + * @ordered + */ + int EHEAP_GRAPH__NODES = GraphPackage.EGRAPH__NODES; + + /** + * The feature id for the 'Edges' containment reference. + * + * + * @generated + * @ordered + */ + int EHEAP_GRAPH__EDGES = GraphPackage.EGRAPH__EDGES; + + /** + * The number of structural features of the 'EHeap Graph' class. + * + * + * @generated + * @ordered + */ + int EHEAP_GRAPH_FEATURE_COUNT = GraphPackage.EGRAPH_FEATURE_COUNT + 0; + + + /** + * Returns the meta object for class '{@link com.ibm.wala.ecore.java.pointerAnalysis.EPointer EPointer}'. + * + * + * @return the meta object for class 'EPointer'. + * @see com.ibm.wala.ecore.java.pointerAnalysis.EPointer + * @generated + */ + EClass getEPointer(); + + /** + * Returns the meta object for class '{@link com.ibm.wala.ecore.java.pointerAnalysis.EInstanceField EInstance Field}'. + * + * + * @return the meta object for class 'EInstance Field'. + * @see com.ibm.wala.ecore.java.pointerAnalysis.EInstanceField + * @generated + */ + EClass getEInstanceField(); + + /** + * Returns the meta object for the attribute '{@link com.ibm.wala.ecore.java.pointerAnalysis.EInstanceField#getFieldName Field Name}'. + * + * + * @return the meta object for the attribute 'Field Name'. + * @see com.ibm.wala.ecore.java.pointerAnalysis.EInstanceField#getFieldName() + * @see #getEInstanceField() + * @generated + */ + EAttribute getEInstanceField_FieldName(); + + /** + * Returns the meta object for class '{@link com.ibm.wala.ecore.java.pointerAnalysis.EArrayContents EArray Contents}'. + * + * + * @return the meta object for class 'EArray Contents'. + * @see com.ibm.wala.ecore.java.pointerAnalysis.EArrayContents + * @generated + */ + EClass getEArrayContents(); + + /** + * Returns the meta object for the reference '{@link com.ibm.wala.ecore.java.pointerAnalysis.EArrayContents#getJavaClass Java Class}'. + * + * + * @return the meta object for the reference 'Java Class'. + * @see com.ibm.wala.ecore.java.pointerAnalysis.EArrayContents#getJavaClass() + * @see #getEArrayContents() + * @generated + */ + EReference getEArrayContents_JavaClass(); + + /** + * Returns the meta object for class '{@link com.ibm.wala.ecore.java.pointerAnalysis.EStaticField EStatic Field}'. + * + * + * @return the meta object for class 'EStatic Field'. + * @see com.ibm.wala.ecore.java.pointerAnalysis.EStaticField + * @generated + */ + EClass getEStaticField(); + + /** + * Returns the meta object for the attribute '{@link com.ibm.wala.ecore.java.pointerAnalysis.EStaticField#getFieldName Field Name}'. + * + * + * @return the meta object for the attribute 'Field Name'. + * @see com.ibm.wala.ecore.java.pointerAnalysis.EStaticField#getFieldName() + * @see #getEStaticField() + * @generated + */ + EAttribute getEStaticField_FieldName(); + + /** + * Returns the meta object for class '{@link com.ibm.wala.ecore.java.pointerAnalysis.ELocalPointer ELocal Pointer}'. + * + * + * @return the meta object for class 'ELocal Pointer'. + * @see com.ibm.wala.ecore.java.pointerAnalysis.ELocalPointer + * @generated + */ + EClass getELocalPointer(); + + /** + * Returns the meta object for the attribute '{@link com.ibm.wala.ecore.java.pointerAnalysis.ELocalPointer#getValueNumber Value Number}'. + * + * + * @return the meta object for the attribute 'Value Number'. + * @see com.ibm.wala.ecore.java.pointerAnalysis.ELocalPointer#getValueNumber() + * @see #getELocalPointer() + * @generated + */ + EAttribute getELocalPointer_ValueNumber(); + + /** + * Returns the meta object for the reference '{@link com.ibm.wala.ecore.java.pointerAnalysis.ELocalPointer#getJavaMethod Java Method}'. + * + * + * @return the meta object for the reference 'Java Method'. + * @see com.ibm.wala.ecore.java.pointerAnalysis.ELocalPointer#getJavaMethod() + * @see #getELocalPointer() + * @generated + */ + EReference getELocalPointer_JavaMethod(); + + /** + * Returns the meta object for class '{@link com.ibm.wala.ecore.java.pointerAnalysis.EReturnValuePointer EReturn Value Pointer}'. + * + * + * @return the meta object for class 'EReturn Value Pointer'. + * @see com.ibm.wala.ecore.java.pointerAnalysis.EReturnValuePointer + * @generated + */ + EClass getEReturnValuePointer(); + + /** + * Returns the meta object for the attribute '{@link com.ibm.wala.ecore.java.pointerAnalysis.EReturnValuePointer#isIsExceptionalReturnValue Is Exceptional Return Value}'. + * + * + * @return the meta object for the attribute 'Is Exceptional Return Value'. + * @see com.ibm.wala.ecore.java.pointerAnalysis.EReturnValuePointer#isIsExceptionalReturnValue() + * @see #getEReturnValuePointer() + * @generated + */ + EAttribute getEReturnValuePointer_IsExceptionalReturnValue(); + + /** + * Returns the meta object for the reference '{@link com.ibm.wala.ecore.java.pointerAnalysis.EReturnValuePointer#getJavaMethod Java Method}'. + * + * + * @return the meta object for the reference 'Java Method'. + * @see com.ibm.wala.ecore.java.pointerAnalysis.EReturnValuePointer#getJavaMethod() + * @see #getEReturnValuePointer() + * @generated + */ + EReference getEReturnValuePointer_JavaMethod(); + + /** + * Returns the meta object for class '{@link com.ibm.wala.ecore.java.pointerAnalysis.EInstance EInstance}'. + * + * + * @return the meta object for class 'EInstance'. + * @see com.ibm.wala.ecore.java.pointerAnalysis.EInstance + * @generated + */ + EClass getEInstance(); + + /** + * Returns the meta object for class '{@link com.ibm.wala.ecore.java.pointerAnalysis.EJavaClassInstance EJava Class Instance}'. + * + * + * @return the meta object for class 'EJava Class Instance'. + * @see com.ibm.wala.ecore.java.pointerAnalysis.EJavaClassInstance + * @generated + */ + EClass getEJavaClassInstance(); + + /** + * Returns the meta object for the reference '{@link com.ibm.wala.ecore.java.pointerAnalysis.EJavaClassInstance#getJavaClass Java Class}'. + * + * + * @return the meta object for the reference 'Java Class'. + * @see com.ibm.wala.ecore.java.pointerAnalysis.EJavaClassInstance#getJavaClass() + * @see #getEJavaClassInstance() + * @generated + */ + EReference getEJavaClassInstance_JavaClass(); + + /** + * Returns the meta object for class '{@link com.ibm.wala.ecore.java.pointerAnalysis.EHeapGraph EHeap Graph}'. + * + * + * @return the meta object for class 'EHeap Graph'. + * @see com.ibm.wala.ecore.java.pointerAnalysis.EHeapGraph + * @generated + */ + EClass getEHeapGraph(); + + /** + * Returns the factory that creates the instances of the model. + * + * + * @return the factory that creates the instances of the model. + * @generated + */ + PointerAnalysisFactory getPointerAnalysisFactory(); + + /** + * + * Defines literals for the meta objects that represent + *
                                + *
                              • each class,
                              • + *
                              • each feature of each class,
                              • + *
                              • each enum,
                              • + *
                              • and each data type
                              • + *
                              + * + * @generated + */ + interface Literals { + /** + * The meta object literal for the '{@link com.ibm.wala.ecore.java.pointerAnalysis.impl.EPointerImpl EPointer}' class. + * + * + * @see com.ibm.wala.ecore.java.pointerAnalysis.impl.EPointerImpl + * @see com.ibm.wala.ecore.java.pointerAnalysis.impl.PointerAnalysisPackageImpl#getEPointer() + * @generated + */ + EClass EPOINTER = eINSTANCE.getEPointer(); + + /** + * The meta object literal for the '{@link com.ibm.wala.ecore.java.pointerAnalysis.impl.EInstanceFieldImpl EInstance Field}' class. + * + * + * @see com.ibm.wala.ecore.java.pointerAnalysis.impl.EInstanceFieldImpl + * @see com.ibm.wala.ecore.java.pointerAnalysis.impl.PointerAnalysisPackageImpl#getEInstanceField() + * @generated + */ + EClass EINSTANCE_FIELD = eINSTANCE.getEInstanceField(); + + /** + * The meta object literal for the 'Field Name' attribute feature. + * + * + * @generated + */ + EAttribute EINSTANCE_FIELD__FIELD_NAME = eINSTANCE.getEInstanceField_FieldName(); + + /** + * The meta object literal for the '{@link com.ibm.wala.ecore.java.pointerAnalysis.impl.EArrayContentsImpl EArray Contents}' class. + * + * + * @see com.ibm.wala.ecore.java.pointerAnalysis.impl.EArrayContentsImpl + * @see com.ibm.wala.ecore.java.pointerAnalysis.impl.PointerAnalysisPackageImpl#getEArrayContents() + * @generated + */ + EClass EARRAY_CONTENTS = eINSTANCE.getEArrayContents(); + + /** + * The meta object literal for the 'Java Class' reference feature. + * + * + * @generated + */ + EReference EARRAY_CONTENTS__JAVA_CLASS = eINSTANCE.getEArrayContents_JavaClass(); + + /** + * The meta object literal for the '{@link com.ibm.wala.ecore.java.pointerAnalysis.impl.EStaticFieldImpl EStatic Field}' class. + * + * + * @see com.ibm.wala.ecore.java.pointerAnalysis.impl.EStaticFieldImpl + * @see com.ibm.wala.ecore.java.pointerAnalysis.impl.PointerAnalysisPackageImpl#getEStaticField() + * @generated + */ + EClass ESTATIC_FIELD = eINSTANCE.getEStaticField(); + + /** + * The meta object literal for the 'Field Name' attribute feature. + * + * + * @generated + */ + EAttribute ESTATIC_FIELD__FIELD_NAME = eINSTANCE.getEStaticField_FieldName(); + + /** + * The meta object literal for the '{@link com.ibm.wala.ecore.java.pointerAnalysis.impl.ELocalPointerImpl ELocal Pointer}' class. + * + * + * @see com.ibm.wala.ecore.java.pointerAnalysis.impl.ELocalPointerImpl + * @see com.ibm.wala.ecore.java.pointerAnalysis.impl.PointerAnalysisPackageImpl#getELocalPointer() + * @generated + */ + EClass ELOCAL_POINTER = eINSTANCE.getELocalPointer(); + + /** + * The meta object literal for the 'Value Number' attribute feature. + * + * + * @generated + */ + EAttribute ELOCAL_POINTER__VALUE_NUMBER = eINSTANCE.getELocalPointer_ValueNumber(); + + /** + * The meta object literal for the 'Java Method' reference feature. + * + * + * @generated + */ + EReference ELOCAL_POINTER__JAVA_METHOD = eINSTANCE.getELocalPointer_JavaMethod(); + + /** + * The meta object literal for the '{@link com.ibm.wala.ecore.java.pointerAnalysis.impl.EReturnValuePointerImpl EReturn Value Pointer}' class. + * + * + * @see com.ibm.wala.ecore.java.pointerAnalysis.impl.EReturnValuePointerImpl + * @see com.ibm.wala.ecore.java.pointerAnalysis.impl.PointerAnalysisPackageImpl#getEReturnValuePointer() + * @generated + */ + EClass ERETURN_VALUE_POINTER = eINSTANCE.getEReturnValuePointer(); + + /** + * The meta object literal for the 'Is Exceptional Return Value' attribute feature. + * + * + * @generated + */ + EAttribute ERETURN_VALUE_POINTER__IS_EXCEPTIONAL_RETURN_VALUE = eINSTANCE.getEReturnValuePointer_IsExceptionalReturnValue(); + + /** + * The meta object literal for the 'Java Method' reference feature. + * + * + * @generated + */ + EReference ERETURN_VALUE_POINTER__JAVA_METHOD = eINSTANCE.getEReturnValuePointer_JavaMethod(); + + /** + * The meta object literal for the '{@link com.ibm.wala.ecore.java.pointerAnalysis.impl.EInstanceImpl EInstance}' class. + * + * + * @see com.ibm.wala.ecore.java.pointerAnalysis.impl.EInstanceImpl + * @see com.ibm.wala.ecore.java.pointerAnalysis.impl.PointerAnalysisPackageImpl#getEInstance() + * @generated + */ + EClass EINSTANCE = eINSTANCE.getEInstance(); + + /** + * The meta object literal for the '{@link com.ibm.wala.ecore.java.pointerAnalysis.impl.EJavaClassInstanceImpl EJava Class Instance}' class. + * + * + * @see com.ibm.wala.ecore.java.pointerAnalysis.impl.EJavaClassInstanceImpl + * @see com.ibm.wala.ecore.java.pointerAnalysis.impl.PointerAnalysisPackageImpl#getEJavaClassInstance() + * @generated + */ + EClass EJAVA_CLASS_INSTANCE = eINSTANCE.getEJavaClassInstance(); + + /** + * The meta object literal for the 'Java Class' reference feature. + * + * + * @generated + */ + EReference EJAVA_CLASS_INSTANCE__JAVA_CLASS = eINSTANCE.getEJavaClassInstance_JavaClass(); + + /** + * The meta object literal for the '{@link com.ibm.wala.ecore.java.pointerAnalysis.impl.EHeapGraphImpl EHeap Graph}' class. + * + * + * @see com.ibm.wala.ecore.java.pointerAnalysis.impl.EHeapGraphImpl + * @see com.ibm.wala.ecore.java.pointerAnalysis.impl.PointerAnalysisPackageImpl#getEHeapGraph() + * @generated + */ + EClass EHEAP_GRAPH = eINSTANCE.getEHeapGraph(); + + } + +} //PointerAnalysisPackage diff --git a/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/pointerAnalysis/impl/EArrayContentsImpl.java b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/pointerAnalysis/impl/EArrayContentsImpl.java new file mode 100644 index 000000000..688441fcd --- /dev/null +++ b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/pointerAnalysis/impl/EArrayContentsImpl.java @@ -0,0 +1,156 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java.pointerAnalysis.impl; + +import com.ibm.wala.ecore.java.EJavaClass; + +import com.ibm.wala.ecore.java.pointerAnalysis.EArrayContents; +import com.ibm.wala.ecore.java.pointerAnalysis.PointerAnalysisPackage; + +import org.eclipse.emf.common.notify.Notification; + +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.InternalEObject; + +import org.eclipse.emf.ecore.impl.ENotificationImpl; + +/** + * + * An implementation of the model object 'EArray Contents'. + * + *

                              + * The following features are implemented: + *

                                + *
                              • {@link com.ibm.wala.ecore.java.pointerAnalysis.impl.EArrayContentsImpl#getJavaClass Java Class}
                              • + *
                              + *

                              + * + * @generated + */ +public class EArrayContentsImpl extends EPointerImpl implements EArrayContents { + /** + * The cached value of the '{@link #getJavaClass() Java Class}' reference. + * + * + * @see #getJavaClass() + * @generated + * @ordered + */ + protected EJavaClass javaClass = null; + + /** + * + * + * @generated + */ + protected EArrayContentsImpl() { + super(); + } + + /** + * + * + * @generated + */ + protected EClass eStaticClass() { + return PointerAnalysisPackage.Literals.EARRAY_CONTENTS; + } + + /** + * + * + * @generated + */ + public EJavaClass getJavaClass() { + if (javaClass != null && javaClass.eIsProxy()) { + InternalEObject oldJavaClass = (InternalEObject)javaClass; + javaClass = (EJavaClass)eResolveProxy(oldJavaClass); + if (javaClass != oldJavaClass) { + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.RESOLVE, PointerAnalysisPackage.EARRAY_CONTENTS__JAVA_CLASS, oldJavaClass, javaClass)); + } + } + return javaClass; + } + + /** + * + * + * @generated + */ + public EJavaClass basicGetJavaClass() { + return javaClass; + } + + /** + * + * + * @generated + */ + public void setJavaClass(EJavaClass newJavaClass) { + EJavaClass oldJavaClass = javaClass; + javaClass = newJavaClass; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, PointerAnalysisPackage.EARRAY_CONTENTS__JAVA_CLASS, oldJavaClass, javaClass)); + } + + /** + * + * + * @generated + */ + public Object eGet(int featureID, boolean resolve, boolean coreType) { + switch (featureID) { + case PointerAnalysisPackage.EARRAY_CONTENTS__JAVA_CLASS: + if (resolve) return getJavaClass(); + return basicGetJavaClass(); + } + return super.eGet(featureID, resolve, coreType); + } + + /** + * + * + * @generated + */ + public void eSet(int featureID, Object newValue) { + switch (featureID) { + case PointerAnalysisPackage.EARRAY_CONTENTS__JAVA_CLASS: + setJavaClass((EJavaClass)newValue); + return; + } + super.eSet(featureID, newValue); + } + + /** + * + * + * @generated + */ + public void eUnset(int featureID) { + switch (featureID) { + case PointerAnalysisPackage.EARRAY_CONTENTS__JAVA_CLASS: + setJavaClass((EJavaClass)null); + return; + } + super.eUnset(featureID); + } + + /** + * + * + * @generated + */ + public boolean eIsSet(int featureID) { + switch (featureID) { + case PointerAnalysisPackage.EARRAY_CONTENTS__JAVA_CLASS: + return javaClass != null; + } + return super.eIsSet(featureID); + } + +} //EArrayContentsImpl \ No newline at end of file diff --git a/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/pointerAnalysis/impl/EHeapGraphImpl.java b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/pointerAnalysis/impl/EHeapGraphImpl.java new file mode 100644 index 000000000..9cc1b71f4 --- /dev/null +++ b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/pointerAnalysis/impl/EHeapGraphImpl.java @@ -0,0 +1,44 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java.pointerAnalysis.impl; + +import com.ibm.wala.ecore.graph.impl.EGraphImpl; + +import com.ibm.wala.ecore.java.pointerAnalysis.EHeapGraph; +import com.ibm.wala.ecore.java.pointerAnalysis.PointerAnalysisPackage; + +import org.eclipse.emf.ecore.EClass; + +/** + * + * An implementation of the model object 'EHeap Graph'. + * + *

                              + *

                              + * + * @generated + */ +public class EHeapGraphImpl extends EGraphImpl implements EHeapGraph { + /** + * + * + * @generated + */ + protected EHeapGraphImpl() { + super(); + } + + /** + * + * + * @generated + */ + protected EClass eStaticClass() { + return PointerAnalysisPackage.Literals.EHEAP_GRAPH; + } + +} //EHeapGraphImpl \ No newline at end of file diff --git a/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/pointerAnalysis/impl/EInstanceFieldImpl.java b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/pointerAnalysis/impl/EInstanceFieldImpl.java new file mode 100644 index 000000000..a89fbf46c --- /dev/null +++ b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/pointerAnalysis/impl/EInstanceFieldImpl.java @@ -0,0 +1,160 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java.pointerAnalysis.impl; + +import com.ibm.wala.ecore.java.pointerAnalysis.EInstanceField; +import com.ibm.wala.ecore.java.pointerAnalysis.PointerAnalysisPackage; + +import org.eclipse.emf.common.notify.Notification; + +import org.eclipse.emf.ecore.EClass; + +import org.eclipse.emf.ecore.impl.ENotificationImpl; + +/** + * + * An implementation of the model object 'EInstance Field'. + * + *

                              + * The following features are implemented: + *

                                + *
                              • {@link com.ibm.wala.ecore.java.pointerAnalysis.impl.EInstanceFieldImpl#getFieldName Field Name}
                              • + *
                              + *

                              + * + * @generated + */ +public class EInstanceFieldImpl extends EPointerImpl implements EInstanceField { + /** + * The default value of the '{@link #getFieldName() Field Name}' attribute. + * + * + * @see #getFieldName() + * @generated + * @ordered + */ + protected static final String FIELD_NAME_EDEFAULT = null; + + /** + * The cached value of the '{@link #getFieldName() Field Name}' attribute. + * + * + * @see #getFieldName() + * @generated + * @ordered + */ + protected String fieldName = FIELD_NAME_EDEFAULT; + + /** + * + * + * @generated + */ + protected EInstanceFieldImpl() { + super(); + } + + /** + * + * + * @generated + */ + protected EClass eStaticClass() { + return PointerAnalysisPackage.Literals.EINSTANCE_FIELD; + } + + /** + * + * + * @generated + */ + public String getFieldName() { + return fieldName; + } + + /** + * + * + * @generated + */ + public void setFieldName(String newFieldName) { + String oldFieldName = fieldName; + fieldName = newFieldName; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, PointerAnalysisPackage.EINSTANCE_FIELD__FIELD_NAME, oldFieldName, fieldName)); + } + + /** + * + * + * @generated + */ + public Object eGet(int featureID, boolean resolve, boolean coreType) { + switch (featureID) { + case PointerAnalysisPackage.EINSTANCE_FIELD__FIELD_NAME: + return getFieldName(); + } + return super.eGet(featureID, resolve, coreType); + } + + /** + * + * + * @generated + */ + public void eSet(int featureID, Object newValue) { + switch (featureID) { + case PointerAnalysisPackage.EINSTANCE_FIELD__FIELD_NAME: + setFieldName((String)newValue); + return; + } + super.eSet(featureID, newValue); + } + + /** + * + * + * @generated + */ + public void eUnset(int featureID) { + switch (featureID) { + case PointerAnalysisPackage.EINSTANCE_FIELD__FIELD_NAME: + setFieldName(FIELD_NAME_EDEFAULT); + return; + } + super.eUnset(featureID); + } + + /** + * + * + * @generated + */ + public boolean eIsSet(int featureID) { + switch (featureID) { + case PointerAnalysisPackage.EINSTANCE_FIELD__FIELD_NAME: + return FIELD_NAME_EDEFAULT == null ? fieldName != null : !FIELD_NAME_EDEFAULT.equals(fieldName); + } + return super.eIsSet(featureID); + } + + /** + * + * + * @generated + */ + public String toString() { + if (eIsProxy()) return super.toString(); + + StringBuffer result = new StringBuffer(super.toString()); + result.append(" (fieldName: "); + result.append(fieldName); + result.append(')'); + return result.toString(); + } + +} //EInstanceFieldImpl \ No newline at end of file diff --git a/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/pointerAnalysis/impl/EInstanceImpl.java b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/pointerAnalysis/impl/EInstanceImpl.java new file mode 100644 index 000000000..8cbf23e79 --- /dev/null +++ b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/pointerAnalysis/impl/EInstanceImpl.java @@ -0,0 +1,44 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java.pointerAnalysis.impl; + +import com.ibm.wala.ecore.java.pointerAnalysis.EInstance; +import com.ibm.wala.ecore.java.pointerAnalysis.PointerAnalysisPackage; + +import org.eclipse.emf.ecore.EClass; + +import org.eclipse.emf.ecore.impl.EObjectImpl; + +/** + * + * An implementation of the model object 'EInstance'. + * + *

                              + *

                              + * + * @generated + */ +public abstract class EInstanceImpl extends EObjectImpl implements EInstance { + /** + * + * + * @generated + */ + protected EInstanceImpl() { + super(); + } + + /** + * + * + * @generated + */ + protected EClass eStaticClass() { + return PointerAnalysisPackage.Literals.EINSTANCE; + } + +} //EInstanceImpl \ No newline at end of file diff --git a/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/pointerAnalysis/impl/EJavaClassInstanceImpl.java b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/pointerAnalysis/impl/EJavaClassInstanceImpl.java new file mode 100644 index 000000000..a88d6938b --- /dev/null +++ b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/pointerAnalysis/impl/EJavaClassInstanceImpl.java @@ -0,0 +1,156 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java.pointerAnalysis.impl; + +import com.ibm.wala.ecore.java.EJavaClass; + +import com.ibm.wala.ecore.java.pointerAnalysis.EJavaClassInstance; +import com.ibm.wala.ecore.java.pointerAnalysis.PointerAnalysisPackage; + +import org.eclipse.emf.common.notify.Notification; + +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.InternalEObject; + +import org.eclipse.emf.ecore.impl.ENotificationImpl; + +/** + * + * An implementation of the model object 'EJava Class Instance'. + * + *

                              + * The following features are implemented: + *

                                + *
                              • {@link com.ibm.wala.ecore.java.pointerAnalysis.impl.EJavaClassInstanceImpl#getJavaClass Java Class}
                              • + *
                              + *

                              + * + * @generated + */ +public class EJavaClassInstanceImpl extends EInstanceImpl implements EJavaClassInstance { + /** + * The cached value of the '{@link #getJavaClass() Java Class}' reference. + * + * + * @see #getJavaClass() + * @generated + * @ordered + */ + protected EJavaClass javaClass = null; + + /** + * + * + * @generated + */ + protected EJavaClassInstanceImpl() { + super(); + } + + /** + * + * + * @generated + */ + protected EClass eStaticClass() { + return PointerAnalysisPackage.Literals.EJAVA_CLASS_INSTANCE; + } + + /** + * + * + * @generated + */ + public EJavaClass getJavaClass() { + if (javaClass != null && javaClass.eIsProxy()) { + InternalEObject oldJavaClass = (InternalEObject)javaClass; + javaClass = (EJavaClass)eResolveProxy(oldJavaClass); + if (javaClass != oldJavaClass) { + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.RESOLVE, PointerAnalysisPackage.EJAVA_CLASS_INSTANCE__JAVA_CLASS, oldJavaClass, javaClass)); + } + } + return javaClass; + } + + /** + * + * + * @generated + */ + public EJavaClass basicGetJavaClass() { + return javaClass; + } + + /** + * + * + * @generated + */ + public void setJavaClass(EJavaClass newJavaClass) { + EJavaClass oldJavaClass = javaClass; + javaClass = newJavaClass; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, PointerAnalysisPackage.EJAVA_CLASS_INSTANCE__JAVA_CLASS, oldJavaClass, javaClass)); + } + + /** + * + * + * @generated + */ + public Object eGet(int featureID, boolean resolve, boolean coreType) { + switch (featureID) { + case PointerAnalysisPackage.EJAVA_CLASS_INSTANCE__JAVA_CLASS: + if (resolve) return getJavaClass(); + return basicGetJavaClass(); + } + return super.eGet(featureID, resolve, coreType); + } + + /** + * + * + * @generated + */ + public void eSet(int featureID, Object newValue) { + switch (featureID) { + case PointerAnalysisPackage.EJAVA_CLASS_INSTANCE__JAVA_CLASS: + setJavaClass((EJavaClass)newValue); + return; + } + super.eSet(featureID, newValue); + } + + /** + * + * + * @generated + */ + public void eUnset(int featureID) { + switch (featureID) { + case PointerAnalysisPackage.EJAVA_CLASS_INSTANCE__JAVA_CLASS: + setJavaClass((EJavaClass)null); + return; + } + super.eUnset(featureID); + } + + /** + * + * + * @generated + */ + public boolean eIsSet(int featureID) { + switch (featureID) { + case PointerAnalysisPackage.EJAVA_CLASS_INSTANCE__JAVA_CLASS: + return javaClass != null; + } + return super.eIsSet(featureID); + } + +} //EJavaClassInstanceImpl \ No newline at end of file diff --git a/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/pointerAnalysis/impl/ELocalPointerImpl.java b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/pointerAnalysis/impl/ELocalPointerImpl.java new file mode 100644 index 000000000..31e28e314 --- /dev/null +++ b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/pointerAnalysis/impl/ELocalPointerImpl.java @@ -0,0 +1,223 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java.pointerAnalysis.impl; + +import com.ibm.wala.ecore.java.EJavaMethod; + +import com.ibm.wala.ecore.java.pointerAnalysis.ELocalPointer; +import com.ibm.wala.ecore.java.pointerAnalysis.PointerAnalysisPackage; + +import org.eclipse.emf.common.notify.Notification; + +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.InternalEObject; + +import org.eclipse.emf.ecore.impl.ENotificationImpl; + +/** + * + * An implementation of the model object 'ELocal Pointer'. + * + *

                              + * The following features are implemented: + *

                                + *
                              • {@link com.ibm.wala.ecore.java.pointerAnalysis.impl.ELocalPointerImpl#getValueNumber Value Number}
                              • + *
                              • {@link com.ibm.wala.ecore.java.pointerAnalysis.impl.ELocalPointerImpl#getJavaMethod Java Method}
                              • + *
                              + *

                              + * + * @generated + */ +public class ELocalPointerImpl extends EPointerImpl implements ELocalPointer { + /** + * The default value of the '{@link #getValueNumber() Value Number}' attribute. + * + * + * @see #getValueNumber() + * @generated + * @ordered + */ + protected static final int VALUE_NUMBER_EDEFAULT = 0; + + /** + * The cached value of the '{@link #getValueNumber() Value Number}' attribute. + * + * + * @see #getValueNumber() + * @generated + * @ordered + */ + protected int valueNumber = VALUE_NUMBER_EDEFAULT; + + /** + * The cached value of the '{@link #getJavaMethod() Java Method}' reference. + * + * + * @see #getJavaMethod() + * @generated + * @ordered + */ + protected EJavaMethod javaMethod = null; + + /** + * + * + * @generated + */ + protected ELocalPointerImpl() { + super(); + } + + /** + * + * + * @generated + */ + protected EClass eStaticClass() { + return PointerAnalysisPackage.Literals.ELOCAL_POINTER; + } + + /** + * + * + * @generated + */ + public int getValueNumber() { + return valueNumber; + } + + /** + * + * + * @generated + */ + public void setValueNumber(int newValueNumber) { + int oldValueNumber = valueNumber; + valueNumber = newValueNumber; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, PointerAnalysisPackage.ELOCAL_POINTER__VALUE_NUMBER, oldValueNumber, valueNumber)); + } + + /** + * + * + * @generated + */ + public EJavaMethod getJavaMethod() { + if (javaMethod != null && javaMethod.eIsProxy()) { + InternalEObject oldJavaMethod = (InternalEObject)javaMethod; + javaMethod = (EJavaMethod)eResolveProxy(oldJavaMethod); + if (javaMethod != oldJavaMethod) { + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.RESOLVE, PointerAnalysisPackage.ELOCAL_POINTER__JAVA_METHOD, oldJavaMethod, javaMethod)); + } + } + return javaMethod; + } + + /** + * + * + * @generated + */ + public EJavaMethod basicGetJavaMethod() { + return javaMethod; + } + + /** + * + * + * @generated + */ + public void setJavaMethod(EJavaMethod newJavaMethod) { + EJavaMethod oldJavaMethod = javaMethod; + javaMethod = newJavaMethod; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, PointerAnalysisPackage.ELOCAL_POINTER__JAVA_METHOD, oldJavaMethod, javaMethod)); + } + + /** + * + * + * @generated + */ + public Object eGet(int featureID, boolean resolve, boolean coreType) { + switch (featureID) { + case PointerAnalysisPackage.ELOCAL_POINTER__VALUE_NUMBER: + return new Integer(getValueNumber()); + case PointerAnalysisPackage.ELOCAL_POINTER__JAVA_METHOD: + if (resolve) return getJavaMethod(); + return basicGetJavaMethod(); + } + return super.eGet(featureID, resolve, coreType); + } + + /** + * + * + * @generated + */ + public void eSet(int featureID, Object newValue) { + switch (featureID) { + case PointerAnalysisPackage.ELOCAL_POINTER__VALUE_NUMBER: + setValueNumber(((Integer)newValue).intValue()); + return; + case PointerAnalysisPackage.ELOCAL_POINTER__JAVA_METHOD: + setJavaMethod((EJavaMethod)newValue); + return; + } + super.eSet(featureID, newValue); + } + + /** + * + * + * @generated + */ + public void eUnset(int featureID) { + switch (featureID) { + case PointerAnalysisPackage.ELOCAL_POINTER__VALUE_NUMBER: + setValueNumber(VALUE_NUMBER_EDEFAULT); + return; + case PointerAnalysisPackage.ELOCAL_POINTER__JAVA_METHOD: + setJavaMethod((EJavaMethod)null); + return; + } + super.eUnset(featureID); + } + + /** + * + * + * @generated + */ + public boolean eIsSet(int featureID) { + switch (featureID) { + case PointerAnalysisPackage.ELOCAL_POINTER__VALUE_NUMBER: + return valueNumber != VALUE_NUMBER_EDEFAULT; + case PointerAnalysisPackage.ELOCAL_POINTER__JAVA_METHOD: + return javaMethod != null; + } + return super.eIsSet(featureID); + } + + /** + * + * + * @generated + */ + public String toString() { + if (eIsProxy()) return super.toString(); + + StringBuffer result = new StringBuffer(super.toString()); + result.append(" (valueNumber: "); + result.append(valueNumber); + result.append(')'); + return result.toString(); + } + +} //ELocalPointerImpl \ No newline at end of file diff --git a/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/pointerAnalysis/impl/EPointerImpl.java b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/pointerAnalysis/impl/EPointerImpl.java new file mode 100644 index 000000000..593f7626f --- /dev/null +++ b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/pointerAnalysis/impl/EPointerImpl.java @@ -0,0 +1,44 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java.pointerAnalysis.impl; + +import com.ibm.wala.ecore.java.pointerAnalysis.EPointer; +import com.ibm.wala.ecore.java.pointerAnalysis.PointerAnalysisPackage; + +import org.eclipse.emf.ecore.EClass; + +import org.eclipse.emf.ecore.impl.EObjectImpl; + +/** + * + * An implementation of the model object 'EPointer'. + * + *

                              + *

                              + * + * @generated + */ +public abstract class EPointerImpl extends EObjectImpl implements EPointer { + /** + * + * + * @generated + */ + protected EPointerImpl() { + super(); + } + + /** + * + * + * @generated + */ + protected EClass eStaticClass() { + return PointerAnalysisPackage.Literals.EPOINTER; + } + +} //EPointerImpl \ No newline at end of file diff --git a/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/pointerAnalysis/impl/EReturnValuePointerImpl.java b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/pointerAnalysis/impl/EReturnValuePointerImpl.java new file mode 100644 index 000000000..4b3219803 --- /dev/null +++ b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/pointerAnalysis/impl/EReturnValuePointerImpl.java @@ -0,0 +1,223 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java.pointerAnalysis.impl; + +import com.ibm.wala.ecore.java.EJavaMethod; + +import com.ibm.wala.ecore.java.pointerAnalysis.EReturnValuePointer; +import com.ibm.wala.ecore.java.pointerAnalysis.PointerAnalysisPackage; + +import org.eclipse.emf.common.notify.Notification; + +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.InternalEObject; + +import org.eclipse.emf.ecore.impl.ENotificationImpl; + +/** + * + * An implementation of the model object 'EReturn Value Pointer'. + * + *

                              + * The following features are implemented: + *

                                + *
                              • {@link com.ibm.wala.ecore.java.pointerAnalysis.impl.EReturnValuePointerImpl#isIsExceptionalReturnValue Is Exceptional Return Value}
                              • + *
                              • {@link com.ibm.wala.ecore.java.pointerAnalysis.impl.EReturnValuePointerImpl#getJavaMethod Java Method}
                              • + *
                              + *

                              + * + * @generated + */ +public class EReturnValuePointerImpl extends EPointerImpl implements EReturnValuePointer { + /** + * The default value of the '{@link #isIsExceptionalReturnValue() Is Exceptional Return Value}' attribute. + * + * + * @see #isIsExceptionalReturnValue() + * @generated + * @ordered + */ + protected static final boolean IS_EXCEPTIONAL_RETURN_VALUE_EDEFAULT = false; + + /** + * The cached value of the '{@link #isIsExceptionalReturnValue() Is Exceptional Return Value}' attribute. + * + * + * @see #isIsExceptionalReturnValue() + * @generated + * @ordered + */ + protected boolean isExceptionalReturnValue = IS_EXCEPTIONAL_RETURN_VALUE_EDEFAULT; + + /** + * The cached value of the '{@link #getJavaMethod() Java Method}' reference. + * + * + * @see #getJavaMethod() + * @generated + * @ordered + */ + protected EJavaMethod javaMethod = null; + + /** + * + * + * @generated + */ + protected EReturnValuePointerImpl() { + super(); + } + + /** + * + * + * @generated + */ + protected EClass eStaticClass() { + return PointerAnalysisPackage.Literals.ERETURN_VALUE_POINTER; + } + + /** + * + * + * @generated + */ + public boolean isIsExceptionalReturnValue() { + return isExceptionalReturnValue; + } + + /** + * + * + * @generated + */ + public void setIsExceptionalReturnValue(boolean newIsExceptionalReturnValue) { + boolean oldIsExceptionalReturnValue = isExceptionalReturnValue; + isExceptionalReturnValue = newIsExceptionalReturnValue; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, PointerAnalysisPackage.ERETURN_VALUE_POINTER__IS_EXCEPTIONAL_RETURN_VALUE, oldIsExceptionalReturnValue, isExceptionalReturnValue)); + } + + /** + * + * + * @generated + */ + public EJavaMethod getJavaMethod() { + if (javaMethod != null && javaMethod.eIsProxy()) { + InternalEObject oldJavaMethod = (InternalEObject)javaMethod; + javaMethod = (EJavaMethod)eResolveProxy(oldJavaMethod); + if (javaMethod != oldJavaMethod) { + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.RESOLVE, PointerAnalysisPackage.ERETURN_VALUE_POINTER__JAVA_METHOD, oldJavaMethod, javaMethod)); + } + } + return javaMethod; + } + + /** + * + * + * @generated + */ + public EJavaMethod basicGetJavaMethod() { + return javaMethod; + } + + /** + * + * + * @generated + */ + public void setJavaMethod(EJavaMethod newJavaMethod) { + EJavaMethod oldJavaMethod = javaMethod; + javaMethod = newJavaMethod; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, PointerAnalysisPackage.ERETURN_VALUE_POINTER__JAVA_METHOD, oldJavaMethod, javaMethod)); + } + + /** + * + * + * @generated + */ + public Object eGet(int featureID, boolean resolve, boolean coreType) { + switch (featureID) { + case PointerAnalysisPackage.ERETURN_VALUE_POINTER__IS_EXCEPTIONAL_RETURN_VALUE: + return isIsExceptionalReturnValue() ? Boolean.TRUE : Boolean.FALSE; + case PointerAnalysisPackage.ERETURN_VALUE_POINTER__JAVA_METHOD: + if (resolve) return getJavaMethod(); + return basicGetJavaMethod(); + } + return super.eGet(featureID, resolve, coreType); + } + + /** + * + * + * @generated + */ + public void eSet(int featureID, Object newValue) { + switch (featureID) { + case PointerAnalysisPackage.ERETURN_VALUE_POINTER__IS_EXCEPTIONAL_RETURN_VALUE: + setIsExceptionalReturnValue(((Boolean)newValue).booleanValue()); + return; + case PointerAnalysisPackage.ERETURN_VALUE_POINTER__JAVA_METHOD: + setJavaMethod((EJavaMethod)newValue); + return; + } + super.eSet(featureID, newValue); + } + + /** + * + * + * @generated + */ + public void eUnset(int featureID) { + switch (featureID) { + case PointerAnalysisPackage.ERETURN_VALUE_POINTER__IS_EXCEPTIONAL_RETURN_VALUE: + setIsExceptionalReturnValue(IS_EXCEPTIONAL_RETURN_VALUE_EDEFAULT); + return; + case PointerAnalysisPackage.ERETURN_VALUE_POINTER__JAVA_METHOD: + setJavaMethod((EJavaMethod)null); + return; + } + super.eUnset(featureID); + } + + /** + * + * + * @generated + */ + public boolean eIsSet(int featureID) { + switch (featureID) { + case PointerAnalysisPackage.ERETURN_VALUE_POINTER__IS_EXCEPTIONAL_RETURN_VALUE: + return isExceptionalReturnValue != IS_EXCEPTIONAL_RETURN_VALUE_EDEFAULT; + case PointerAnalysisPackage.ERETURN_VALUE_POINTER__JAVA_METHOD: + return javaMethod != null; + } + return super.eIsSet(featureID); + } + + /** + * + * + * @generated + */ + public String toString() { + if (eIsProxy()) return super.toString(); + + StringBuffer result = new StringBuffer(super.toString()); + result.append(" (isExceptionalReturnValue: "); + result.append(isExceptionalReturnValue); + result.append(')'); + return result.toString(); + } + +} //EReturnValuePointerImpl \ No newline at end of file diff --git a/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/pointerAnalysis/impl/EStaticFieldImpl.java b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/pointerAnalysis/impl/EStaticFieldImpl.java new file mode 100644 index 000000000..0a83af731 --- /dev/null +++ b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/pointerAnalysis/impl/EStaticFieldImpl.java @@ -0,0 +1,160 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java.pointerAnalysis.impl; + +import com.ibm.wala.ecore.java.pointerAnalysis.EStaticField; +import com.ibm.wala.ecore.java.pointerAnalysis.PointerAnalysisPackage; + +import org.eclipse.emf.common.notify.Notification; + +import org.eclipse.emf.ecore.EClass; + +import org.eclipse.emf.ecore.impl.ENotificationImpl; + +/** + * + * An implementation of the model object 'EStatic Field'. + * + *

                              + * The following features are implemented: + *

                                + *
                              • {@link com.ibm.wala.ecore.java.pointerAnalysis.impl.EStaticFieldImpl#getFieldName Field Name}
                              • + *
                              + *

                              + * + * @generated + */ +public class EStaticFieldImpl extends EPointerImpl implements EStaticField { + /** + * The default value of the '{@link #getFieldName() Field Name}' attribute. + * + * + * @see #getFieldName() + * @generated + * @ordered + */ + protected static final String FIELD_NAME_EDEFAULT = null; + + /** + * The cached value of the '{@link #getFieldName() Field Name}' attribute. + * + * + * @see #getFieldName() + * @generated + * @ordered + */ + protected String fieldName = FIELD_NAME_EDEFAULT; + + /** + * + * + * @generated + */ + protected EStaticFieldImpl() { + super(); + } + + /** + * + * + * @generated + */ + protected EClass eStaticClass() { + return PointerAnalysisPackage.Literals.ESTATIC_FIELD; + } + + /** + * + * + * @generated + */ + public String getFieldName() { + return fieldName; + } + + /** + * + * + * @generated + */ + public void setFieldName(String newFieldName) { + String oldFieldName = fieldName; + fieldName = newFieldName; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, PointerAnalysisPackage.ESTATIC_FIELD__FIELD_NAME, oldFieldName, fieldName)); + } + + /** + * + * + * @generated + */ + public Object eGet(int featureID, boolean resolve, boolean coreType) { + switch (featureID) { + case PointerAnalysisPackage.ESTATIC_FIELD__FIELD_NAME: + return getFieldName(); + } + return super.eGet(featureID, resolve, coreType); + } + + /** + * + * + * @generated + */ + public void eSet(int featureID, Object newValue) { + switch (featureID) { + case PointerAnalysisPackage.ESTATIC_FIELD__FIELD_NAME: + setFieldName((String)newValue); + return; + } + super.eSet(featureID, newValue); + } + + /** + * + * + * @generated + */ + public void eUnset(int featureID) { + switch (featureID) { + case PointerAnalysisPackage.ESTATIC_FIELD__FIELD_NAME: + setFieldName(FIELD_NAME_EDEFAULT); + return; + } + super.eUnset(featureID); + } + + /** + * + * + * @generated + */ + public boolean eIsSet(int featureID) { + switch (featureID) { + case PointerAnalysisPackage.ESTATIC_FIELD__FIELD_NAME: + return FIELD_NAME_EDEFAULT == null ? fieldName != null : !FIELD_NAME_EDEFAULT.equals(fieldName); + } + return super.eIsSet(featureID); + } + + /** + * + * + * @generated + */ + public String toString() { + if (eIsProxy()) return super.toString(); + + StringBuffer result = new StringBuffer(super.toString()); + result.append(" (fieldName: "); + result.append(fieldName); + result.append(')'); + return result.toString(); + } + +} //EStaticFieldImpl \ No newline at end of file diff --git a/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/pointerAnalysis/impl/PointerAnalysisFactoryImpl.java b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/pointerAnalysis/impl/PointerAnalysisFactoryImpl.java new file mode 100644 index 000000000..067d6ee56 --- /dev/null +++ b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/pointerAnalysis/impl/PointerAnalysisFactoryImpl.java @@ -0,0 +1,163 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java.pointerAnalysis.impl; + +import com.ibm.wala.ecore.java.pointerAnalysis.*; + +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EPackage; + +import org.eclipse.emf.ecore.impl.EFactoryImpl; + +import org.eclipse.emf.ecore.plugin.EcorePlugin; + +/** + * + * An implementation of the model Factory. + * + * @generated + */ +public class PointerAnalysisFactoryImpl extends EFactoryImpl implements PointerAnalysisFactory { + /** + * Creates the default factory implementation. + * + * + * @generated + */ + public static PointerAnalysisFactory init() { + try { + PointerAnalysisFactory thePointerAnalysisFactory = (PointerAnalysisFactory)EPackage.Registry.INSTANCE.getEFactory("http:///com/ibm/wala/wala.ecore.java.pointerAnalysis"); + if (thePointerAnalysisFactory != null) { + return thePointerAnalysisFactory; + } + } + catch (Exception exception) { + EcorePlugin.INSTANCE.log(exception); + } + return new PointerAnalysisFactoryImpl(); + } + + /** + * Creates an instance of the factory. + * + * + * @generated + */ + public PointerAnalysisFactoryImpl() { + super(); + } + + /** + * + * + * @generated + */ + public EObject create(EClass eClass) { + switch (eClass.getClassifierID()) { + case PointerAnalysisPackage.EINSTANCE_FIELD: return createEInstanceField(); + case PointerAnalysisPackage.EARRAY_CONTENTS: return createEArrayContents(); + case PointerAnalysisPackage.ESTATIC_FIELD: return createEStaticField(); + case PointerAnalysisPackage.ELOCAL_POINTER: return createELocalPointer(); + case PointerAnalysisPackage.ERETURN_VALUE_POINTER: return createEReturnValuePointer(); + case PointerAnalysisPackage.EJAVA_CLASS_INSTANCE: return createEJavaClassInstance(); + case PointerAnalysisPackage.EHEAP_GRAPH: return createEHeapGraph(); + default: + throw new IllegalArgumentException("The class '" + eClass.getName() + "' is not a valid classifier"); + } + } + + /** + * + * + * @generated + */ + public EInstanceField createEInstanceField() { + EInstanceFieldImpl eInstanceField = new EInstanceFieldImpl(); + return eInstanceField; + } + + /** + * + * + * @generated + */ + public EArrayContents createEArrayContents() { + EArrayContentsImpl eArrayContents = new EArrayContentsImpl(); + return eArrayContents; + } + + /** + * + * + * @generated + */ + public EStaticField createEStaticField() { + EStaticFieldImpl eStaticField = new EStaticFieldImpl(); + return eStaticField; + } + + /** + * + * + * @generated + */ + public ELocalPointer createELocalPointer() { + ELocalPointerImpl eLocalPointer = new ELocalPointerImpl(); + return eLocalPointer; + } + + /** + * + * + * @generated + */ + public EReturnValuePointer createEReturnValuePointer() { + EReturnValuePointerImpl eReturnValuePointer = new EReturnValuePointerImpl(); + return eReturnValuePointer; + } + + /** + * + * + * @generated + */ + public EJavaClassInstance createEJavaClassInstance() { + EJavaClassInstanceImpl eJavaClassInstance = new EJavaClassInstanceImpl(); + return eJavaClassInstance; + } + + /** + * + * + * @generated + */ + public EHeapGraph createEHeapGraph() { + EHeapGraphImpl eHeapGraph = new EHeapGraphImpl(); + return eHeapGraph; + } + + /** + * + * + * @generated + */ + public PointerAnalysisPackage getPointerAnalysisPackage() { + return (PointerAnalysisPackage)getEPackage(); + } + + /** + * + * + * @deprecated + * @generated + */ + public static PointerAnalysisPackage getPackage() { + return PointerAnalysisPackage.eINSTANCE; + } + +} //PointerAnalysisFactoryImpl diff --git a/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/pointerAnalysis/impl/PointerAnalysisPackageImpl.java b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/pointerAnalysis/impl/PointerAnalysisPackageImpl.java new file mode 100644 index 000000000..17a463d50 --- /dev/null +++ b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/pointerAnalysis/impl/PointerAnalysisPackageImpl.java @@ -0,0 +1,496 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java.pointerAnalysis.impl; + +import com.ibm.wala.ecore.common.CommonPackage; + +import com.ibm.wala.ecore.common.impl.CommonPackageImpl; + +import com.ibm.wala.ecore.graph.GraphPackage; + +import com.ibm.wala.ecore.graph.impl.GraphPackageImpl; + +import com.ibm.wala.ecore.j2ee.scope.J2EEScopePackage; + +import com.ibm.wala.ecore.j2ee.scope.impl.J2EEScopePackageImpl; + +import com.ibm.wala.ecore.java.JavaPackage; + +import com.ibm.wala.ecore.java.callGraph.CallGraphPackage; + +import com.ibm.wala.ecore.java.callGraph.impl.CallGraphPackageImpl; + +import com.ibm.wala.ecore.java.impl.JavaPackageImpl; + +import com.ibm.wala.ecore.java.pointerAnalysis.EArrayContents; +import com.ibm.wala.ecore.java.pointerAnalysis.EHeapGraph; +import com.ibm.wala.ecore.java.pointerAnalysis.EInstance; +import com.ibm.wala.ecore.java.pointerAnalysis.EInstanceField; +import com.ibm.wala.ecore.java.pointerAnalysis.EJavaClassInstance; +import com.ibm.wala.ecore.java.pointerAnalysis.ELocalPointer; +import com.ibm.wala.ecore.java.pointerAnalysis.EPointer; +import com.ibm.wala.ecore.java.pointerAnalysis.EReturnValuePointer; +import com.ibm.wala.ecore.java.pointerAnalysis.EStaticField; +import com.ibm.wala.ecore.java.pointerAnalysis.PointerAnalysisFactory; +import com.ibm.wala.ecore.java.pointerAnalysis.PointerAnalysisPackage; + +import com.ibm.wala.ecore.java.scope.JavaScopePackage; + +import com.ibm.wala.ecore.java.scope.impl.JavaScopePackageImpl; + +import com.ibm.wala.ecore.perf.PerfPackage; + +import com.ibm.wala.ecore.perf.impl.PerfPackageImpl; + +import com.ibm.wala.ecore.regex.RegexPackage; + +import com.ibm.wala.ecore.regex.impl.RegexPackageImpl; + +import org.eclipse.emf.ecore.EAttribute; +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EPackage; +import org.eclipse.emf.ecore.EReference; + +import org.eclipse.emf.ecore.impl.EPackageImpl; + +/** + * + * An implementation of the model Package. + * + * @generated + */ +public class PointerAnalysisPackageImpl extends EPackageImpl implements PointerAnalysisPackage { + /** + * + * + * @generated + */ + private EClass ePointerEClass = null; + + /** + * + * + * @generated + */ + private EClass eInstanceFieldEClass = null; + + /** + * + * + * @generated + */ + private EClass eArrayContentsEClass = null; + + /** + * + * + * @generated + */ + private EClass eStaticFieldEClass = null; + + /** + * + * + * @generated + */ + private EClass eLocalPointerEClass = null; + + /** + * + * + * @generated + */ + private EClass eReturnValuePointerEClass = null; + + /** + * + * + * @generated + */ + private EClass eInstanceEClass = null; + + /** + * + * + * @generated + */ + private EClass eJavaClassInstanceEClass = null; + + /** + * + * + * @generated + */ + private EClass eHeapGraphEClass = null; + + /** + * Creates an instance of the model Package, registered with + * {@link org.eclipse.emf.ecore.EPackage.Registry EPackage.Registry} by the package + * package URI value. + *

                              Note: the correct way to create the package is via the static + * factory method {@link #init init()}, which also performs + * initialization of the package, or returns the registered package, + * if one already exists. + * + * + * @see org.eclipse.emf.ecore.EPackage.Registry + * @see com.ibm.wala.ecore.java.pointerAnalysis.PointerAnalysisPackage#eNS_URI + * @see #init() + * @generated + */ + private PointerAnalysisPackageImpl() { + super(eNS_URI, PointerAnalysisFactory.eINSTANCE); + } + + /** + * + * + * @generated + */ + private static boolean isInited = false; + + /** + * Creates, registers, and initializes the Package for this + * model, and for any others upon which it depends. Simple + * dependencies are satisfied by calling this method on all + * dependent packages before doing anything else. This method drives + * initialization for interdependent packages directly, in parallel + * with this package, itself. + *

                              Of this package and its interdependencies, all packages which + * have not yet been registered by their URI values are first created + * and registered. The packages are then initialized in two steps: + * meta-model objects for all of the packages are created before any + * are initialized, since one package's meta-model objects may refer to + * those of another. + *

                              Invocation of this method will not affect any packages that have + * already been initialized. + * + * + * @see #eNS_URI + * @see #createPackageContents() + * @see #initializePackageContents() + * @generated + */ + public static PointerAnalysisPackage init() { + if (isInited) return (PointerAnalysisPackage)EPackage.Registry.INSTANCE.getEPackage(PointerAnalysisPackage.eNS_URI); + + // Obtain or create and register package + PointerAnalysisPackageImpl thePointerAnalysisPackage = (PointerAnalysisPackageImpl)(EPackage.Registry.INSTANCE.getEPackage(eNS_URI) instanceof PointerAnalysisPackageImpl ? EPackage.Registry.INSTANCE.getEPackage(eNS_URI) : new PointerAnalysisPackageImpl()); + + isInited = true; + + // Obtain or create and register interdependencies + GraphPackageImpl theGraphPackage = (GraphPackageImpl)(EPackage.Registry.INSTANCE.getEPackage(GraphPackage.eNS_URI) instanceof GraphPackageImpl ? EPackage.Registry.INSTANCE.getEPackage(GraphPackage.eNS_URI) : GraphPackage.eINSTANCE); + CommonPackageImpl theCommonPackage = (CommonPackageImpl)(EPackage.Registry.INSTANCE.getEPackage(CommonPackage.eNS_URI) instanceof CommonPackageImpl ? EPackage.Registry.INSTANCE.getEPackage(CommonPackage.eNS_URI) : CommonPackage.eINSTANCE); + RegexPackageImpl theRegexPackage = (RegexPackageImpl)(EPackage.Registry.INSTANCE.getEPackage(RegexPackage.eNS_URI) instanceof RegexPackageImpl ? EPackage.Registry.INSTANCE.getEPackage(RegexPackage.eNS_URI) : RegexPackage.eINSTANCE); + PerfPackageImpl thePerfPackage = (PerfPackageImpl)(EPackage.Registry.INSTANCE.getEPackage(PerfPackage.eNS_URI) instanceof PerfPackageImpl ? EPackage.Registry.INSTANCE.getEPackage(PerfPackage.eNS_URI) : PerfPackage.eINSTANCE); + JavaPackageImpl theJavaPackage = (JavaPackageImpl)(EPackage.Registry.INSTANCE.getEPackage(JavaPackage.eNS_URI) instanceof JavaPackageImpl ? EPackage.Registry.INSTANCE.getEPackage(JavaPackage.eNS_URI) : JavaPackage.eINSTANCE); + CallGraphPackageImpl theCallGraphPackage = (CallGraphPackageImpl)(EPackage.Registry.INSTANCE.getEPackage(CallGraphPackage.eNS_URI) instanceof CallGraphPackageImpl ? EPackage.Registry.INSTANCE.getEPackage(CallGraphPackage.eNS_URI) : CallGraphPackage.eINSTANCE); + JavaScopePackageImpl theJavaScopePackage = (JavaScopePackageImpl)(EPackage.Registry.INSTANCE.getEPackage(JavaScopePackage.eNS_URI) instanceof JavaScopePackageImpl ? EPackage.Registry.INSTANCE.getEPackage(JavaScopePackage.eNS_URI) : JavaScopePackage.eINSTANCE); + J2EEScopePackageImpl theJ2EEScopePackage = (J2EEScopePackageImpl)(EPackage.Registry.INSTANCE.getEPackage(J2EEScopePackage.eNS_URI) instanceof J2EEScopePackageImpl ? EPackage.Registry.INSTANCE.getEPackage(J2EEScopePackage.eNS_URI) : J2EEScopePackage.eINSTANCE); + + // Create package meta-data objects + thePointerAnalysisPackage.createPackageContents(); + theGraphPackage.createPackageContents(); + theCommonPackage.createPackageContents(); + theRegexPackage.createPackageContents(); + thePerfPackage.createPackageContents(); + theJavaPackage.createPackageContents(); + theCallGraphPackage.createPackageContents(); + theJavaScopePackage.createPackageContents(); + theJ2EEScopePackage.createPackageContents(); + + // Initialize created meta-data + thePointerAnalysisPackage.initializePackageContents(); + theGraphPackage.initializePackageContents(); + theCommonPackage.initializePackageContents(); + theRegexPackage.initializePackageContents(); + thePerfPackage.initializePackageContents(); + theJavaPackage.initializePackageContents(); + theCallGraphPackage.initializePackageContents(); + theJavaScopePackage.initializePackageContents(); + theJ2EEScopePackage.initializePackageContents(); + + // Mark meta-data to indicate it can't be changed + thePointerAnalysisPackage.freeze(); + + return thePointerAnalysisPackage; + } + + /** + * + * + * @generated + */ + public EClass getEPointer() { + return ePointerEClass; + } + + /** + * + * + * @generated + */ + public EClass getEInstanceField() { + return eInstanceFieldEClass; + } + + /** + * + * + * @generated + */ + public EAttribute getEInstanceField_FieldName() { + return (EAttribute)eInstanceFieldEClass.getEStructuralFeatures().get(0); + } + + /** + * + * + * @generated + */ + public EClass getEArrayContents() { + return eArrayContentsEClass; + } + + /** + * + * + * @generated + */ + public EReference getEArrayContents_JavaClass() { + return (EReference)eArrayContentsEClass.getEStructuralFeatures().get(0); + } + + /** + * + * + * @generated + */ + public EClass getEStaticField() { + return eStaticFieldEClass; + } + + /** + * + * + * @generated + */ + public EAttribute getEStaticField_FieldName() { + return (EAttribute)eStaticFieldEClass.getEStructuralFeatures().get(0); + } + + /** + * + * + * @generated + */ + public EClass getELocalPointer() { + return eLocalPointerEClass; + } + + /** + * + * + * @generated + */ + public EAttribute getELocalPointer_ValueNumber() { + return (EAttribute)eLocalPointerEClass.getEStructuralFeatures().get(0); + } + + /** + * + * + * @generated + */ + public EReference getELocalPointer_JavaMethod() { + return (EReference)eLocalPointerEClass.getEStructuralFeatures().get(1); + } + + /** + * + * + * @generated + */ + public EClass getEReturnValuePointer() { + return eReturnValuePointerEClass; + } + + /** + * + * + * @generated + */ + public EAttribute getEReturnValuePointer_IsExceptionalReturnValue() { + return (EAttribute)eReturnValuePointerEClass.getEStructuralFeatures().get(0); + } + + /** + * + * + * @generated + */ + public EReference getEReturnValuePointer_JavaMethod() { + return (EReference)eReturnValuePointerEClass.getEStructuralFeatures().get(1); + } + + /** + * + * + * @generated + */ + public EClass getEInstance() { + return eInstanceEClass; + } + + /** + * + * + * @generated + */ + public EClass getEJavaClassInstance() { + return eJavaClassInstanceEClass; + } + + /** + * + * + * @generated + */ + public EReference getEJavaClassInstance_JavaClass() { + return (EReference)eJavaClassInstanceEClass.getEStructuralFeatures().get(0); + } + + /** + * + * + * @generated + */ + public EClass getEHeapGraph() { + return eHeapGraphEClass; + } + + /** + * + * + * @generated + */ + public PointerAnalysisFactory getPointerAnalysisFactory() { + return (PointerAnalysisFactory)getEFactoryInstance(); + } + + /** + * + * + * @generated + */ + private boolean isCreated = false; + + /** + * Creates the meta-model objects for the package. This method is + * guarded to have no affect on any invocation but its first. + * + * + * @generated + */ + public void createPackageContents() { + if (isCreated) return; + isCreated = true; + + // Create classes and their features + ePointerEClass = createEClass(EPOINTER); + + eInstanceFieldEClass = createEClass(EINSTANCE_FIELD); + createEAttribute(eInstanceFieldEClass, EINSTANCE_FIELD__FIELD_NAME); + + eArrayContentsEClass = createEClass(EARRAY_CONTENTS); + createEReference(eArrayContentsEClass, EARRAY_CONTENTS__JAVA_CLASS); + + eStaticFieldEClass = createEClass(ESTATIC_FIELD); + createEAttribute(eStaticFieldEClass, ESTATIC_FIELD__FIELD_NAME); + + eLocalPointerEClass = createEClass(ELOCAL_POINTER); + createEAttribute(eLocalPointerEClass, ELOCAL_POINTER__VALUE_NUMBER); + createEReference(eLocalPointerEClass, ELOCAL_POINTER__JAVA_METHOD); + + eReturnValuePointerEClass = createEClass(ERETURN_VALUE_POINTER); + createEAttribute(eReturnValuePointerEClass, ERETURN_VALUE_POINTER__IS_EXCEPTIONAL_RETURN_VALUE); + createEReference(eReturnValuePointerEClass, ERETURN_VALUE_POINTER__JAVA_METHOD); + + eInstanceEClass = createEClass(EINSTANCE); + + eJavaClassInstanceEClass = createEClass(EJAVA_CLASS_INSTANCE); + createEReference(eJavaClassInstanceEClass, EJAVA_CLASS_INSTANCE__JAVA_CLASS); + + eHeapGraphEClass = createEClass(EHEAP_GRAPH); + } + + /** + * + * + * @generated + */ + private boolean isInitialized = false; + + /** + * Complete the initialization of the package and its meta-model. This + * method is guarded to have no affect on any invocation but its first. + * + * + * @generated + */ + public void initializePackageContents() { + if (isInitialized) return; + isInitialized = true; + + // Initialize package + setName(eNAME); + setNsPrefix(eNS_PREFIX); + setNsURI(eNS_URI); + + // Obtain other dependent packages + JavaPackage theJavaPackage = (JavaPackage)EPackage.Registry.INSTANCE.getEPackage(JavaPackage.eNS_URI); + GraphPackage theGraphPackage = (GraphPackage)EPackage.Registry.INSTANCE.getEPackage(GraphPackage.eNS_URI); + + // Add supertypes to classes + eInstanceFieldEClass.getESuperTypes().add(this.getEPointer()); + eArrayContentsEClass.getESuperTypes().add(this.getEPointer()); + eStaticFieldEClass.getESuperTypes().add(this.getEPointer()); + eLocalPointerEClass.getESuperTypes().add(this.getEPointer()); + eReturnValuePointerEClass.getESuperTypes().add(this.getEPointer()); + eJavaClassInstanceEClass.getESuperTypes().add(this.getEInstance()); + eHeapGraphEClass.getESuperTypes().add(theGraphPackage.getEGraph()); + + // Initialize classes and features; add operations and parameters + initEClass(ePointerEClass, EPointer.class, "EPointer", IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); + + initEClass(eInstanceFieldEClass, EInstanceField.class, "EInstanceField", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); + initEAttribute(getEInstanceField_FieldName(), ecorePackage.getEString(), "fieldName", null, 0, 1, EInstanceField.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); + + initEClass(eArrayContentsEClass, EArrayContents.class, "EArrayContents", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); + initEReference(getEArrayContents_JavaClass(), theJavaPackage.getEJavaClass(), null, "javaClass", null, 1, 1, EArrayContents.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_COMPOSITE, IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); + + initEClass(eStaticFieldEClass, EStaticField.class, "EStaticField", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); + initEAttribute(getEStaticField_FieldName(), ecorePackage.getEString(), "fieldName", null, 0, 1, EStaticField.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); + + initEClass(eLocalPointerEClass, ELocalPointer.class, "ELocalPointer", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); + initEAttribute(getELocalPointer_ValueNumber(), ecorePackage.getEInt(), "valueNumber", null, 1, 1, ELocalPointer.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); + initEReference(getELocalPointer_JavaMethod(), theJavaPackage.getEJavaMethod(), null, "javaMethod", null, 1, 1, ELocalPointer.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_COMPOSITE, IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); + + initEClass(eReturnValuePointerEClass, EReturnValuePointer.class, "EReturnValuePointer", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); + initEAttribute(getEReturnValuePointer_IsExceptionalReturnValue(), ecorePackage.getEBoolean(), "isExceptionalReturnValue", null, 0, 1, EReturnValuePointer.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); + initEReference(getEReturnValuePointer_JavaMethod(), theJavaPackage.getEJavaMethod(), null, "javaMethod", null, 1, 1, EReturnValuePointer.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_COMPOSITE, IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); + + initEClass(eInstanceEClass, EInstance.class, "EInstance", IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); + + initEClass(eJavaClassInstanceEClass, EJavaClassInstance.class, "EJavaClassInstance", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); + initEReference(getEJavaClassInstance_JavaClass(), theJavaPackage.getEJavaClass(), null, "javaClass", null, 1, 1, EJavaClassInstance.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_COMPOSITE, IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); + + initEClass(eHeapGraphEClass, EHeapGraph.class, "EHeapGraph", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); + } + +} //PointerAnalysisPackageImpl diff --git a/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/pointerAnalysis/util/PointerAnalysisAdapterFactory.java b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/pointerAnalysis/util/PointerAnalysisAdapterFactory.java new file mode 100644 index 000000000..d61400e1f --- /dev/null +++ b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/pointerAnalysis/util/PointerAnalysisAdapterFactory.java @@ -0,0 +1,275 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java.pointerAnalysis.util; + +import com.ibm.wala.ecore.graph.EGraph; + +import com.ibm.wala.ecore.java.pointerAnalysis.*; + +import org.eclipse.emf.common.notify.Adapter; +import org.eclipse.emf.common.notify.Notifier; + +import org.eclipse.emf.common.notify.impl.AdapterFactoryImpl; + +import org.eclipse.emf.ecore.EObject; + +/** + * + * The Adapter Factory for the model. + * It provides an adapter createXXX method for each class of the model. + * + * @see com.ibm.wala.ecore.java.pointerAnalysis.PointerAnalysisPackage + * @generated + */ +public class PointerAnalysisAdapterFactory extends AdapterFactoryImpl { + /** + * The cached model package. + * + * + * @generated + */ + protected static PointerAnalysisPackage modelPackage; + + /** + * Creates an instance of the adapter factory. + * + * + * @generated + */ + public PointerAnalysisAdapterFactory() { + if (modelPackage == null) { + modelPackage = PointerAnalysisPackage.eINSTANCE; + } + } + + /** + * Returns whether this factory is applicable for the type of the object. + * + * This implementation returns true if the object is either the model's package or is an instance object of the model. + * + * @return whether this factory is applicable for the type of the object. + * @generated + */ + public boolean isFactoryForType(Object object) { + if (object == modelPackage) { + return true; + } + if (object instanceof EObject) { + return ((EObject)object).eClass().getEPackage() == modelPackage; + } + return false; + } + + /** + * The switch the delegates to the createXXX methods. + * + * + * @generated + */ + protected PointerAnalysisSwitch modelSwitch = + new PointerAnalysisSwitch() { + public Object caseEPointer(EPointer object) { + return createEPointerAdapter(); + } + public Object caseEInstanceField(EInstanceField object) { + return createEInstanceFieldAdapter(); + } + public Object caseEArrayContents(EArrayContents object) { + return createEArrayContentsAdapter(); + } + public Object caseEStaticField(EStaticField object) { + return createEStaticFieldAdapter(); + } + public Object caseELocalPointer(ELocalPointer object) { + return createELocalPointerAdapter(); + } + public Object caseEReturnValuePointer(EReturnValuePointer object) { + return createEReturnValuePointerAdapter(); + } + public Object caseEInstance(EInstance object) { + return createEInstanceAdapter(); + } + public Object caseEJavaClassInstance(EJavaClassInstance object) { + return createEJavaClassInstanceAdapter(); + } + public Object caseEHeapGraph(EHeapGraph object) { + return createEHeapGraphAdapter(); + } + public Object caseEGraph(EGraph object) { + return createEGraphAdapter(); + } + public Object defaultCase(EObject object) { + return createEObjectAdapter(); + } + }; + + /** + * Creates an adapter for the target. + * + * + * @param target the object to adapt. + * @return the adapter for the target. + * @generated + */ + public Adapter createAdapter(Notifier target) { + return (Adapter)modelSwitch.doSwitch((EObject)target); + } + + + /** + * Creates a new adapter for an object of class '{@link com.ibm.wala.ecore.java.pointerAnalysis.EPointer EPointer}'. + * + * This default implementation returns null so that we can easily ignore cases; + * it's useful to ignore a case when inheritance will catch all the cases anyway. + * + * @return the new adapter. + * @see com.ibm.wala.ecore.java.pointerAnalysis.EPointer + * @generated + */ + public Adapter createEPointerAdapter() { + return null; + } + + /** + * Creates a new adapter for an object of class '{@link com.ibm.wala.ecore.java.pointerAnalysis.EInstanceField EInstance Field}'. + * + * This default implementation returns null so that we can easily ignore cases; + * it's useful to ignore a case when inheritance will catch all the cases anyway. + * + * @return the new adapter. + * @see com.ibm.wala.ecore.java.pointerAnalysis.EInstanceField + * @generated + */ + public Adapter createEInstanceFieldAdapter() { + return null; + } + + /** + * Creates a new adapter for an object of class '{@link com.ibm.wala.ecore.java.pointerAnalysis.EArrayContents EArray Contents}'. + * + * This default implementation returns null so that we can easily ignore cases; + * it's useful to ignore a case when inheritance will catch all the cases anyway. + * + * @return the new adapter. + * @see com.ibm.wala.ecore.java.pointerAnalysis.EArrayContents + * @generated + */ + public Adapter createEArrayContentsAdapter() { + return null; + } + + /** + * Creates a new adapter for an object of class '{@link com.ibm.wala.ecore.java.pointerAnalysis.EStaticField EStatic Field}'. + * + * This default implementation returns null so that we can easily ignore cases; + * it's useful to ignore a case when inheritance will catch all the cases anyway. + * + * @return the new adapter. + * @see com.ibm.wala.ecore.java.pointerAnalysis.EStaticField + * @generated + */ + public Adapter createEStaticFieldAdapter() { + return null; + } + + /** + * Creates a new adapter for an object of class '{@link com.ibm.wala.ecore.java.pointerAnalysis.ELocalPointer ELocal Pointer}'. + * + * This default implementation returns null so that we can easily ignore cases; + * it's useful to ignore a case when inheritance will catch all the cases anyway. + * + * @return the new adapter. + * @see com.ibm.wala.ecore.java.pointerAnalysis.ELocalPointer + * @generated + */ + public Adapter createELocalPointerAdapter() { + return null; + } + + /** + * Creates a new adapter for an object of class '{@link com.ibm.wala.ecore.java.pointerAnalysis.EReturnValuePointer EReturn Value Pointer}'. + * + * This default implementation returns null so that we can easily ignore cases; + * it's useful to ignore a case when inheritance will catch all the cases anyway. + * + * @return the new adapter. + * @see com.ibm.wala.ecore.java.pointerAnalysis.EReturnValuePointer + * @generated + */ + public Adapter createEReturnValuePointerAdapter() { + return null; + } + + /** + * Creates a new adapter for an object of class '{@link com.ibm.wala.ecore.java.pointerAnalysis.EInstance EInstance}'. + * + * This default implementation returns null so that we can easily ignore cases; + * it's useful to ignore a case when inheritance will catch all the cases anyway. + * + * @return the new adapter. + * @see com.ibm.wala.ecore.java.pointerAnalysis.EInstance + * @generated + */ + public Adapter createEInstanceAdapter() { + return null; + } + + /** + * Creates a new adapter for an object of class '{@link com.ibm.wala.ecore.java.pointerAnalysis.EJavaClassInstance EJava Class Instance}'. + * + * This default implementation returns null so that we can easily ignore cases; + * it's useful to ignore a case when inheritance will catch all the cases anyway. + * + * @return the new adapter. + * @see com.ibm.wala.ecore.java.pointerAnalysis.EJavaClassInstance + * @generated + */ + public Adapter createEJavaClassInstanceAdapter() { + return null; + } + + /** + * Creates a new adapter for an object of class '{@link com.ibm.wala.ecore.java.pointerAnalysis.EHeapGraph EHeap Graph}'. + * + * This default implementation returns null so that we can easily ignore cases; + * it's useful to ignore a case when inheritance will catch all the cases anyway. + * + * @return the new adapter. + * @see com.ibm.wala.ecore.java.pointerAnalysis.EHeapGraph + * @generated + */ + public Adapter createEHeapGraphAdapter() { + return null; + } + + /** + * Creates a new adapter for an object of class '{@link com.ibm.wala.ecore.graph.EGraph EGraph}'. + * + * This default implementation returns null so that we can easily ignore cases; + * it's useful to ignore a case when inheritance will catch all the cases anyway. + * + * @return the new adapter. + * @see com.ibm.wala.ecore.graph.EGraph + * @generated + */ + public Adapter createEGraphAdapter() { + return null; + } + + /** + * Creates a new adapter for the default case. + * + * This default implementation returns null. + * + * @return the new adapter. + * @generated + */ + public Adapter createEObjectAdapter() { + return null; + } + +} //PointerAnalysisAdapterFactory diff --git a/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/pointerAnalysis/util/PointerAnalysisSwitch.java b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/pointerAnalysis/util/PointerAnalysisSwitch.java new file mode 100644 index 000000000..b72675663 --- /dev/null +++ b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/pointerAnalysis/util/PointerAnalysisSwitch.java @@ -0,0 +1,322 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java.pointerAnalysis.util; + +import com.ibm.wala.ecore.graph.EGraph; + +import com.ibm.wala.ecore.java.pointerAnalysis.*; + +import java.util.List; + +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EObject; + +/** + * + * The Switch for the model's inheritance hierarchy. + * It supports the call {@link #doSwitch(EObject) doSwitch(object)} + * to invoke the caseXXX method for each class of the model, + * starting with the actual class of the object + * and proceeding up the inheritance hierarchy + * until a non-null result is returned, + * which is the result of the switch. + * + * @see com.ibm.wala.ecore.java.pointerAnalysis.PointerAnalysisPackage + * @generated + */ +public class PointerAnalysisSwitch { + /** + * The cached model package + * + * + * @generated + */ + protected static PointerAnalysisPackage modelPackage; + + /** + * Creates an instance of the switch. + * + * + * @generated + */ + public PointerAnalysisSwitch() { + if (modelPackage == null) { + modelPackage = PointerAnalysisPackage.eINSTANCE; + } + } + + /** + * Calls caseXXX for each class of the model until one returns a non null result; it yields that result. + * + * + * @return the first non-null result returned by a caseXXX call. + * @generated + */ + public Object doSwitch(EObject theEObject) { + return doSwitch(theEObject.eClass(), theEObject); + } + + /** + * Calls caseXXX for each class of the model until one returns a non null result; it yields that result. + * + * + * @return the first non-null result returned by a caseXXX call. + * @generated + */ + protected Object doSwitch(EClass theEClass, EObject theEObject) { + if (theEClass.eContainer() == modelPackage) { + return doSwitch(theEClass.getClassifierID(), theEObject); + } + else { + List eSuperTypes = theEClass.getESuperTypes(); + return + eSuperTypes.isEmpty() ? + defaultCase(theEObject) : + doSwitch((EClass)eSuperTypes.get(0), theEObject); + } + } + + /** + * Calls caseXXX for each class of the model until one returns a non null result; it yields that result. + * + * + * @return the first non-null result returned by a caseXXX call. + * @generated + */ + protected Object doSwitch(int classifierID, EObject theEObject) { + switch (classifierID) { + case PointerAnalysisPackage.EPOINTER: { + EPointer ePointer = (EPointer)theEObject; + Object result = caseEPointer(ePointer); + if (result == null) result = defaultCase(theEObject); + return result; + } + case PointerAnalysisPackage.EINSTANCE_FIELD: { + EInstanceField eInstanceField = (EInstanceField)theEObject; + Object result = caseEInstanceField(eInstanceField); + if (result == null) result = caseEPointer(eInstanceField); + if (result == null) result = defaultCase(theEObject); + return result; + } + case PointerAnalysisPackage.EARRAY_CONTENTS: { + EArrayContents eArrayContents = (EArrayContents)theEObject; + Object result = caseEArrayContents(eArrayContents); + if (result == null) result = caseEPointer(eArrayContents); + if (result == null) result = defaultCase(theEObject); + return result; + } + case PointerAnalysisPackage.ESTATIC_FIELD: { + EStaticField eStaticField = (EStaticField)theEObject; + Object result = caseEStaticField(eStaticField); + if (result == null) result = caseEPointer(eStaticField); + if (result == null) result = defaultCase(theEObject); + return result; + } + case PointerAnalysisPackage.ELOCAL_POINTER: { + ELocalPointer eLocalPointer = (ELocalPointer)theEObject; + Object result = caseELocalPointer(eLocalPointer); + if (result == null) result = caseEPointer(eLocalPointer); + if (result == null) result = defaultCase(theEObject); + return result; + } + case PointerAnalysisPackage.ERETURN_VALUE_POINTER: { + EReturnValuePointer eReturnValuePointer = (EReturnValuePointer)theEObject; + Object result = caseEReturnValuePointer(eReturnValuePointer); + if (result == null) result = caseEPointer(eReturnValuePointer); + if (result == null) result = defaultCase(theEObject); + return result; + } + case PointerAnalysisPackage.EINSTANCE: { + EInstance eInstance = (EInstance)theEObject; + Object result = caseEInstance(eInstance); + if (result == null) result = defaultCase(theEObject); + return result; + } + case PointerAnalysisPackage.EJAVA_CLASS_INSTANCE: { + EJavaClassInstance eJavaClassInstance = (EJavaClassInstance)theEObject; + Object result = caseEJavaClassInstance(eJavaClassInstance); + if (result == null) result = caseEInstance(eJavaClassInstance); + if (result == null) result = defaultCase(theEObject); + return result; + } + case PointerAnalysisPackage.EHEAP_GRAPH: { + EHeapGraph eHeapGraph = (EHeapGraph)theEObject; + Object result = caseEHeapGraph(eHeapGraph); + if (result == null) result = caseEGraph(eHeapGraph); + if (result == null) result = defaultCase(theEObject); + return result; + } + default: return defaultCase(theEObject); + } + } + + /** + * Returns the result of interpretting the object as an instance of 'EPointer'. + * + * This implementation returns null; + * returning a non-null result will terminate the switch. + * + * @param object the target of the switch. + * @return the result of interpretting the object as an instance of 'EPointer'. + * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject) + * @generated + */ + public Object caseEPointer(EPointer object) { + return null; + } + + /** + * Returns the result of interpretting the object as an instance of 'EInstance Field'. + * + * This implementation returns null; + * returning a non-null result will terminate the switch. + * + * @param object the target of the switch. + * @return the result of interpretting the object as an instance of 'EInstance Field'. + * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject) + * @generated + */ + public Object caseEInstanceField(EInstanceField object) { + return null; + } + + /** + * Returns the result of interpretting the object as an instance of 'EArray Contents'. + * + * This implementation returns null; + * returning a non-null result will terminate the switch. + * + * @param object the target of the switch. + * @return the result of interpretting the object as an instance of 'EArray Contents'. + * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject) + * @generated + */ + public Object caseEArrayContents(EArrayContents object) { + return null; + } + + /** + * Returns the result of interpretting the object as an instance of 'EStatic Field'. + * + * This implementation returns null; + * returning a non-null result will terminate the switch. + * + * @param object the target of the switch. + * @return the result of interpretting the object as an instance of 'EStatic Field'. + * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject) + * @generated + */ + public Object caseEStaticField(EStaticField object) { + return null; + } + + /** + * Returns the result of interpretting the object as an instance of 'ELocal Pointer'. + * + * This implementation returns null; + * returning a non-null result will terminate the switch. + * + * @param object the target of the switch. + * @return the result of interpretting the object as an instance of 'ELocal Pointer'. + * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject) + * @generated + */ + public Object caseELocalPointer(ELocalPointer object) { + return null; + } + + /** + * Returns the result of interpretting the object as an instance of 'EReturn Value Pointer'. + * + * This implementation returns null; + * returning a non-null result will terminate the switch. + * + * @param object the target of the switch. + * @return the result of interpretting the object as an instance of 'EReturn Value Pointer'. + * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject) + * @generated + */ + public Object caseEReturnValuePointer(EReturnValuePointer object) { + return null; + } + + /** + * Returns the result of interpretting the object as an instance of 'EInstance'. + * + * This implementation returns null; + * returning a non-null result will terminate the switch. + * + * @param object the target of the switch. + * @return the result of interpretting the object as an instance of 'EInstance'. + * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject) + * @generated + */ + public Object caseEInstance(EInstance object) { + return null; + } + + /** + * Returns the result of interpretting the object as an instance of 'EJava Class Instance'. + * + * This implementation returns null; + * returning a non-null result will terminate the switch. + * + * @param object the target of the switch. + * @return the result of interpretting the object as an instance of 'EJava Class Instance'. + * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject) + * @generated + */ + public Object caseEJavaClassInstance(EJavaClassInstance object) { + return null; + } + + /** + * Returns the result of interpretting the object as an instance of 'EHeap Graph'. + * + * This implementation returns null; + * returning a non-null result will terminate the switch. + * + * @param object the target of the switch. + * @return the result of interpretting the object as an instance of 'EHeap Graph'. + * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject) + * @generated + */ + public Object caseEHeapGraph(EHeapGraph object) { + return null; + } + + /** + * Returns the result of interpretting the object as an instance of 'EGraph'. + * + * This implementation returns null; + * returning a non-null result will terminate the switch. + * + * @param object the target of the switch. + * @return the result of interpretting the object as an instance of 'EGraph'. + * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject) + * @generated + */ + public Object caseEGraph(EGraph object) { + return null; + } + + /** + * Returns the result of interpretting the object as an instance of 'EObject'. + * + * This implementation returns null; + * returning a non-null result will terminate the switch, but this is the last case anyway. + * + * @param object the target of the switch. + * @return the result of interpretting the object as an instance of 'EObject'. + * @see #doSwitch(org.eclipse.emf.ecore.EObject) + * @generated + */ + public Object defaultCase(EObject object) { + return null; + } + +} //PointerAnalysisSwitch diff --git a/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/EBuiltInModule.java b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/EBuiltInModule.java new file mode 100644 index 000000000..dc4d4699a --- /dev/null +++ b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/EBuiltInModule.java @@ -0,0 +1,56 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java.scope; + + +/** + * + * A representation of the model object 'EBuilt In Module'. + * + * + *

                              + * The following features are supported: + *

                                + *
                              • {@link com.ibm.wala.ecore.java.scope.EBuiltInModule#getId Id}
                              • + *
                              + *

                              + * + * @see com.ibm.wala.ecore.java.scope.JavaScopePackage#getEBuiltInModule() + * @model + * @generated + */ +public interface EBuiltInModule extends EModule { + /** + * Returns the value of the 'Id' attribute. + * The literals are from the enumeration {@link com.ibm.wala.ecore.java.scope.EBuiltInResource}. + * + *

                              + * If the meaning of the 'Id' attribute isn't clear, + * there really should be more of a description here... + *

                              + * + * @return the value of the 'Id' attribute. + * @see com.ibm.wala.ecore.java.scope.EBuiltInResource + * @see #setId(EBuiltInResource) + * @see com.ibm.wala.ecore.java.scope.JavaScopePackage#getEBuiltInModule_Id() + * @model required="true" + * @generated + */ + EBuiltInResource getId(); + + /** + * Sets the value of the '{@link com.ibm.wala.ecore.java.scope.EBuiltInModule#getId Id}' attribute. + * + * + * @param value the new value of the 'Id' attribute. + * @see com.ibm.wala.ecore.java.scope.EBuiltInResource + * @see #getId() + * @generated + */ + void setId(EBuiltInResource value); + +} // EBuiltInModule \ No newline at end of file diff --git a/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/EBuiltInResource.java b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/EBuiltInResource.java new file mode 100644 index 000000000..a75ccc5f4 --- /dev/null +++ b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/EBuiltInResource.java @@ -0,0 +1,205 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java.scope; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import org.eclipse.emf.common.util.AbstractEnumerator; + +/** + * + * A representation of the literals of the enumeration 'EBuilt In Resource', + * and utility methods for working with them. + * + * @see com.ibm.wala.ecore.java.scope.JavaScopePackage#getEBuiltInResource() + * @model + * @generated + */ +public final class EBuiltInResource extends AbstractEnumerator { + /** + * The 'Default J2SE Libs' literal value. + * + *

                              + * If the meaning of 'Default J2SE Libs' literal object isn't clear, + * there really should be more of a description here... + *

                              + * + * @see #DEFAULT_J2SE_LIBS_LITERAL + * @model name="DefaultJ2SELibs" + * @generated + * @ordered + */ + public static final int DEFAULT_J2SE_LIBS = 0; + + /** + * The 'Default J2EE Libs' literal value. + * + *

                              + * If the meaning of 'Default J2EE Libs' literal object isn't clear, + * there really should be more of a description here... + *

                              + * + * @see #DEFAULT_J2EE_LIBS_LITERAL + * @model name="DefaultJ2EELibs" + * @generated + * @ordered + */ + public static final int DEFAULT_J2EE_LIBS = 1; + + /** + * The 'Primordial jar model' literal value. + * + *

                              + * If the meaning of 'Primordial jar model' literal object isn't clear, + * there really should be more of a description here... + *

                              + * + * @see #PRIMORDIAL_JAR_MODEL_LITERAL + * @model name="primordial_jar_model" + * @generated + * @ordered + */ + public static final int PRIMORDIAL_JAR_MODEL = 2; + + /** + * The 'Extension jar model' literal value. + * + *

                              + * If the meaning of 'Extension jar model' literal object isn't clear, + * there really should be more of a description here... + *

                              + * + * @see #EXTENSION_JAR_MODEL_LITERAL + * @model name="extension_jar_model" + * @generated + * @ordered + */ + public static final int EXTENSION_JAR_MODEL = 3; + + /** + * The 'Default J2SE Libs' literal object. + * + * + * @see #DEFAULT_J2SE_LIBS + * @generated + * @ordered + */ + public static final EBuiltInResource DEFAULT_J2SE_LIBS_LITERAL = new EBuiltInResource(DEFAULT_J2SE_LIBS, "DefaultJ2SELibs", "DefaultJ2SELibs"); + + /** + * The 'Default J2EE Libs' literal object. + * + * + * @see #DEFAULT_J2EE_LIBS + * @generated + * @ordered + */ + public static final EBuiltInResource DEFAULT_J2EE_LIBS_LITERAL = new EBuiltInResource(DEFAULT_J2EE_LIBS, "DefaultJ2EELibs", "DefaultJ2EELibs"); + + /** + * The 'Primordial jar model' literal object. + * + * + * @see #PRIMORDIAL_JAR_MODEL + * @generated + * @ordered + */ + public static final EBuiltInResource PRIMORDIAL_JAR_MODEL_LITERAL = new EBuiltInResource(PRIMORDIAL_JAR_MODEL, "primordial_jar_model", "primordial_jar_model"); + + /** + * The 'Extension jar model' literal object. + * + * + * @see #EXTENSION_JAR_MODEL + * @generated + * @ordered + */ + public static final EBuiltInResource EXTENSION_JAR_MODEL_LITERAL = new EBuiltInResource(EXTENSION_JAR_MODEL, "extension_jar_model", "extension_jar_model"); + + /** + * An array of all the 'EBuilt In Resource' enumerators. + * + * + * @generated + */ + private static final EBuiltInResource[] VALUES_ARRAY = + new EBuiltInResource[] { + DEFAULT_J2SE_LIBS_LITERAL, + DEFAULT_J2EE_LIBS_LITERAL, + PRIMORDIAL_JAR_MODEL_LITERAL, + EXTENSION_JAR_MODEL_LITERAL, + }; + + /** + * A public read-only list of all the 'EBuilt In Resource' enumerators. + * + * + * @generated + */ + public static final List VALUES = Collections.unmodifiableList(Arrays.asList(VALUES_ARRAY)); + + /** + * Returns the 'EBuilt In Resource' literal with the specified literal value. + * + * + * @generated + */ + public static EBuiltInResource get(String literal) { + for (int i = 0; i < VALUES_ARRAY.length; ++i) { + EBuiltInResource result = VALUES_ARRAY[i]; + if (result.toString().equals(literal)) { + return result; + } + } + return null; + } + + /** + * Returns the 'EBuilt In Resource' literal with the specified name. + * + * + * @generated + */ + public static EBuiltInResource getByName(String name) { + for (int i = 0; i < VALUES_ARRAY.length; ++i) { + EBuiltInResource result = VALUES_ARRAY[i]; + if (result.getName().equals(name)) { + return result; + } + } + return null; + } + + /** + * Returns the 'EBuilt In Resource' literal with the specified integer value. + * + * + * @generated + */ + public static EBuiltInResource get(int value) { + switch (value) { + case DEFAULT_J2SE_LIBS: return DEFAULT_J2SE_LIBS_LITERAL; + case DEFAULT_J2EE_LIBS: return DEFAULT_J2EE_LIBS_LITERAL; + case PRIMORDIAL_JAR_MODEL: return PRIMORDIAL_JAR_MODEL_LITERAL; + case EXTENSION_JAR_MODEL: return EXTENSION_JAR_MODEL_LITERAL; + } + return null; + } + + /** + * Only this class can construct instances. + * + * + * @generated + */ + private EBuiltInResource(int value, String name, String literal) { + super(value, name, literal); + } + +} //EBuiltInResource diff --git a/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/EClassFile.java b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/EClassFile.java new file mode 100644 index 000000000..dcaadd444 --- /dev/null +++ b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/EClassFile.java @@ -0,0 +1,21 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java.scope; + + +/** + * + * A representation of the model object 'EClass File'. + * + * + * + * @see com.ibm.wala.ecore.java.scope.JavaScopePackage#getEClassFile() + * @model + * @generated + */ +public interface EClassFile extends EFile { +} // EClassFile \ No newline at end of file diff --git a/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/EClassLoader.java b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/EClassLoader.java new file mode 100644 index 000000000..8f3ca010e --- /dev/null +++ b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/EClassLoader.java @@ -0,0 +1,73 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java.scope; + +import org.eclipse.emf.common.util.EList; + +import org.eclipse.emf.ecore.EObject; + +/** + * + * A representation of the model object 'EClass Loader'. + * + * + *

                              + * The following features are supported: + *

                                + *
                              • {@link com.ibm.wala.ecore.java.scope.EClassLoader#getModules Modules}
                              • + *
                              • {@link com.ibm.wala.ecore.java.scope.EClassLoader#getLoaderName Loader Name}
                              • + *
                              + *

                              + * + * @see com.ibm.wala.ecore.java.scope.JavaScopePackage#getEClassLoader() + * @model + * @generated + */ +public interface EClassLoader extends EObject { + /** + * Returns the value of the 'Modules' containment reference list. + * The list contents are of type {@link com.ibm.wala.ecore.java.scope.EModule}. + * + *

                              + * If the meaning of the 'Modules' containment reference list isn't clear, + * there really should be more of a description here... + *

                              + * + * @return the value of the 'Modules' containment reference list. + * @see com.ibm.wala.ecore.java.scope.JavaScopePackage#getEClassLoader_Modules() + * @model type="com.ibm.wala.ecore.java.scope.EModule" containment="true" required="true" + * @generated + */ + EList getModules(); + + /** + * Returns the value of the 'Loader Name' attribute. + * + *

                              + * If the meaning of the 'Loader Name' attribute isn't clear, + * there really should be more of a description here... + *

                              + * + * @return the value of the 'Loader Name' attribute. + * @see #setLoaderName(String) + * @see com.ibm.wala.ecore.java.scope.JavaScopePackage#getEClassLoader_LoaderName() + * @model + * @generated + */ + String getLoaderName(); + + /** + * Sets the value of the '{@link com.ibm.wala.ecore.java.scope.EClassLoader#getLoaderName Loader Name}' attribute. + * + * + * @param value the new value of the 'Loader Name' attribute. + * @see #getLoaderName() + * @generated + */ + void setLoaderName(String value); + +} // EClassLoader \ No newline at end of file diff --git a/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/EClasspath.java b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/EClasspath.java new file mode 100644 index 000000000..8dc93dc15 --- /dev/null +++ b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/EClasspath.java @@ -0,0 +1,54 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java.scope; + +import org.eclipse.emf.ecore.EObject; + +/** + * + * A representation of the model object 'EClasspath'. + * + * + *

                              + * The following features are supported: + *

                                + *
                              • {@link com.ibm.wala.ecore.java.scope.EClasspath#getString String}
                              • + *
                              + *

                              + * + * @see com.ibm.wala.ecore.java.scope.JavaScopePackage#getEClasspath() + * @model + * @generated + */ +public interface EClasspath extends EObject { + /** + * Returns the value of the 'String' attribute. + * + *

                              + * If the meaning of the 'String' attribute isn't clear, + * there really should be more of a description here... + *

                              + * + * @return the value of the 'String' attribute. + * @see #setString(String) + * @see com.ibm.wala.ecore.java.scope.JavaScopePackage#getEClasspath_String() + * @model required="true" + * @generated + */ + String getString(); + + /** + * Sets the value of the '{@link com.ibm.wala.ecore.java.scope.EClasspath#getString String}' attribute. + * + * + * @param value the new value of the 'String' attribute. + * @see #getString() + * @generated + */ + void setString(String value); + +} // EClasspath \ No newline at end of file diff --git a/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/EFile.java b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/EFile.java new file mode 100644 index 000000000..2c760b60b --- /dev/null +++ b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/EFile.java @@ -0,0 +1,53 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java.scope; + + +/** + * + * A representation of the model object 'EFile'. + * + * + *

                              + * The following features are supported: + *

                                + *
                              • {@link com.ibm.wala.ecore.java.scope.EFile#getUrl Url}
                              • + *
                              + *

                              + * + * @see com.ibm.wala.ecore.java.scope.JavaScopePackage#getEFile() + * @model + * @generated + */ +public interface EFile extends EModule { + /** + * Returns the value of the 'Url' attribute. + * + *

                              + * If the meaning of the 'Url' attribute isn't clear, + * there really should be more of a description here... + *

                              + * + * @return the value of the 'Url' attribute. + * @see #setUrl(String) + * @see com.ibm.wala.ecore.java.scope.JavaScopePackage#getEFile_Url() + * @model required="true" + * @generated + */ + String getUrl(); + + /** + * Sets the value of the '{@link com.ibm.wala.ecore.java.scope.EFile#getUrl Url}' attribute. + * + * + * @param value the new value of the 'Url' attribute. + * @see #getUrl() + * @generated + */ + void setUrl(String value); + +} // EFile \ No newline at end of file diff --git a/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/EJarFile.java b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/EJarFile.java new file mode 100644 index 000000000..22f8df932 --- /dev/null +++ b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/EJarFile.java @@ -0,0 +1,53 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java.scope; + + +/** + * + * A representation of the model object 'EJar File'. + * + * + *

                              + * The following features are supported: + *

                                + *
                              • {@link com.ibm.wala.ecore.java.scope.EJarFile#getUrl Url}
                              • + *
                              + *

                              + * + * @see com.ibm.wala.ecore.java.scope.JavaScopePackage#getEJarFile() + * @model + * @generated + */ +public interface EJarFile extends EModule { + /** + * Returns the value of the 'Url' attribute. + * + *

                              + * If the meaning of the 'Url' attribute isn't clear, + * there really should be more of a description here... + *

                              + * + * @return the value of the 'Url' attribute. + * @see #setUrl(String) + * @see com.ibm.wala.ecore.java.scope.JavaScopePackage#getEJarFile_Url() + * @model required="true" + * @generated + */ + String getUrl(); + + /** + * Sets the value of the '{@link com.ibm.wala.ecore.java.scope.EJarFile#getUrl Url}' attribute. + * + * + * @param value the new value of the 'Url' attribute. + * @see #getUrl() + * @generated + */ + void setUrl(String value); + +} // EJarFile \ No newline at end of file diff --git a/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/EJavaAnalysisScope.java b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/EJavaAnalysisScope.java new file mode 100644 index 000000000..3e27594f3 --- /dev/null +++ b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/EJavaAnalysisScope.java @@ -0,0 +1,73 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java.scope; + +import org.eclipse.emf.common.util.EList; + +import org.eclipse.emf.ecore.EObject; + +/** + * + * A representation of the model object 'EJava Analysis Scope'. + * + * + *

                              + * The following features are supported: + *

                                + *
                              • {@link com.ibm.wala.ecore.java.scope.EJavaAnalysisScope#getLoaders Loaders}
                              • + *
                              • {@link com.ibm.wala.ecore.java.scope.EJavaAnalysisScope#getExclusionFileName Exclusion File Name}
                              • + *
                              + *

                              + * + * @see com.ibm.wala.ecore.java.scope.JavaScopePackage#getEJavaAnalysisScope() + * @model + * @generated + */ +public interface EJavaAnalysisScope extends EObject { + /** + * Returns the value of the 'Loaders' containment reference list. + * The list contents are of type {@link com.ibm.wala.ecore.java.scope.EClassLoader}. + * + *

                              + * If the meaning of the 'Loaders' containment reference list isn't clear, + * there really should be more of a description here... + *

                              + * + * @return the value of the 'Loaders' containment reference list. + * @see com.ibm.wala.ecore.java.scope.JavaScopePackage#getEJavaAnalysisScope_Loaders() + * @model type="com.ibm.wala.ecore.java.scope.EClassLoader" containment="true" required="true" + * @generated + */ + EList getLoaders(); + + /** + * Returns the value of the 'Exclusion File Name' attribute. + * + *

                              + * If the meaning of the 'Exclusion File Name' attribute isn't clear, + * there really should be more of a description here... + *

                              + * + * @return the value of the 'Exclusion File Name' attribute. + * @see #setExclusionFileName(String) + * @see com.ibm.wala.ecore.java.scope.JavaScopePackage#getEJavaAnalysisScope_ExclusionFileName() + * @model + * @generated + */ + String getExclusionFileName(); + + /** + * Sets the value of the '{@link com.ibm.wala.ecore.java.scope.EJavaAnalysisScope#getExclusionFileName Exclusion File Name}' attribute. + * + * + * @param value the new value of the 'Exclusion File Name' attribute. + * @see #getExclusionFileName() + * @generated + */ + void setExclusionFileName(String value); + +} // EJavaAnalysisScope \ No newline at end of file diff --git a/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/EModule.java b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/EModule.java new file mode 100644 index 000000000..ea516f0ab --- /dev/null +++ b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/EModule.java @@ -0,0 +1,22 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java.scope; + +import org.eclipse.emf.ecore.EObject; + +/** + * + * A representation of the model object 'EModule'. + * + * + * + * @see com.ibm.wala.ecore.java.scope.JavaScopePackage#getEModule() + * @model interface="true" abstract="true" + * @generated + */ +public interface EModule extends EObject { +} // EModule \ No newline at end of file diff --git a/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/ESourceFile.java b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/ESourceFile.java new file mode 100644 index 000000000..dd0382503 --- /dev/null +++ b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/ESourceFile.java @@ -0,0 +1,21 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java.scope; + + +/** + * + * A representation of the model object 'ESource File'. + * + * + * + * @see com.ibm.wala.ecore.java.scope.JavaScopePackage#getESourceFile() + * @model + * @generated + */ +public interface ESourceFile extends EFile { +} // ESourceFile \ No newline at end of file diff --git a/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/EStandardClassLoader.java b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/EStandardClassLoader.java new file mode 100644 index 000000000..a8d9dcc33 --- /dev/null +++ b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/EStandardClassLoader.java @@ -0,0 +1,205 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java.scope; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import org.eclipse.emf.common.util.AbstractEnumerator; + +/** + * + * A representation of the literals of the enumeration 'EStandard Class Loader', + * and utility methods for working with them. + * + * @see com.ibm.wala.ecore.java.scope.JavaScopePackage#getEStandardClassLoader() + * @model + * @generated + */ +public final class EStandardClassLoader extends AbstractEnumerator { + /** + * The 'Primordial' literal value. + * + *

                              + * If the meaning of 'Primordial' literal object isn't clear, + * there really should be more of a description here... + *

                              + * + * @see #PRIMORDIAL_LITERAL + * @model name="Primordial" + * @generated + * @ordered + */ + public static final int PRIMORDIAL = 0; + + /** + * The 'Extension' literal value. + * + *

                              + * If the meaning of 'Extension' literal object isn't clear, + * there really should be more of a description here... + *

                              + * + * @see #EXTENSION_LITERAL + * @model name="Extension" + * @generated + * @ordered + */ + public static final int EXTENSION = 1; + + /** + * The 'Application' literal value. + * + *

                              + * If the meaning of 'Application' literal object isn't clear, + * there really should be more of a description here... + *

                              + * + * @see #APPLICATION_LITERAL + * @model name="Application" + * @generated + * @ordered + */ + public static final int APPLICATION = 2; + + /** + * The 'Synthetic' literal value. + * + *

                              + * If the meaning of 'Synthetic' literal object isn't clear, + * there really should be more of a description here... + *

                              + * + * @see #SYNTHETIC_LITERAL + * @model name="Synthetic" + * @generated + * @ordered + */ + public static final int SYNTHETIC = 4; + + /** + * The 'Primordial' literal object. + * + * + * @see #PRIMORDIAL + * @generated + * @ordered + */ + public static final EStandardClassLoader PRIMORDIAL_LITERAL = new EStandardClassLoader(PRIMORDIAL, "Primordial", "Primordial"); + + /** + * The 'Extension' literal object. + * + * + * @see #EXTENSION + * @generated + * @ordered + */ + public static final EStandardClassLoader EXTENSION_LITERAL = new EStandardClassLoader(EXTENSION, "Extension", "Extension"); + + /** + * The 'Application' literal object. + * + * + * @see #APPLICATION + * @generated + * @ordered + */ + public static final EStandardClassLoader APPLICATION_LITERAL = new EStandardClassLoader(APPLICATION, "Application", "Application"); + + /** + * The 'Synthetic' literal object. + * + * + * @see #SYNTHETIC + * @generated + * @ordered + */ + public static final EStandardClassLoader SYNTHETIC_LITERAL = new EStandardClassLoader(SYNTHETIC, "Synthetic", "Synthetic"); + + /** + * An array of all the 'EStandard Class Loader' enumerators. + * + * + * @generated + */ + private static final EStandardClassLoader[] VALUES_ARRAY = + new EStandardClassLoader[] { + PRIMORDIAL_LITERAL, + EXTENSION_LITERAL, + APPLICATION_LITERAL, + SYNTHETIC_LITERAL, + }; + + /** + * A public read-only list of all the 'EStandard Class Loader' enumerators. + * + * + * @generated + */ + public static final List VALUES = Collections.unmodifiableList(Arrays.asList(VALUES_ARRAY)); + + /** + * Returns the 'EStandard Class Loader' literal with the specified literal value. + * + * + * @generated + */ + public static EStandardClassLoader get(String literal) { + for (int i = 0; i < VALUES_ARRAY.length; ++i) { + EStandardClassLoader result = VALUES_ARRAY[i]; + if (result.toString().equals(literal)) { + return result; + } + } + return null; + } + + /** + * Returns the 'EStandard Class Loader' literal with the specified name. + * + * + * @generated + */ + public static EStandardClassLoader getByName(String name) { + for (int i = 0; i < VALUES_ARRAY.length; ++i) { + EStandardClassLoader result = VALUES_ARRAY[i]; + if (result.getName().equals(name)) { + return result; + } + } + return null; + } + + /** + * Returns the 'EStandard Class Loader' literal with the specified integer value. + * + * + * @generated + */ + public static EStandardClassLoader get(int value) { + switch (value) { + case PRIMORDIAL: return PRIMORDIAL_LITERAL; + case EXTENSION: return EXTENSION_LITERAL; + case APPLICATION: return APPLICATION_LITERAL; + case SYNTHETIC: return SYNTHETIC_LITERAL; + } + return null; + } + + /** + * Only this class can construct instances. + * + * + * @generated + */ + private EStandardClassLoader(int value, String name, String literal) { + super(value, name, literal); + } + +} //EStandardClassLoader diff --git a/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/JavaScopeFactory.java b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/JavaScopeFactory.java new file mode 100644 index 000000000..1e7461e9e --- /dev/null +++ b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/JavaScopeFactory.java @@ -0,0 +1,109 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java.scope; + +import org.eclipse.emf.ecore.EFactory; + +/** + * + * The Factory for the model. + * It provides a create method for each non-abstract class of the model. + * + * @see com.ibm.wala.ecore.java.scope.JavaScopePackage + * @generated + */ +public interface JavaScopeFactory extends EFactory { + /** + * The singleton instance of the factory. + * + * + * @generated + */ + JavaScopeFactory eINSTANCE = com.ibm.wala.ecore.java.scope.impl.JavaScopeFactoryImpl.init(); + + /** + * Returns a new object of class 'EJava Analysis Scope'. + * + * + * @return a new object of class 'EJava Analysis Scope'. + * @generated + */ + EJavaAnalysisScope createEJavaAnalysisScope(); + + /** + * Returns a new object of class 'EClass Loader'. + * + * + * @return a new object of class 'EClass Loader'. + * @generated + */ + EClassLoader createEClassLoader(); + + /** + * Returns a new object of class 'EBuilt In Module'. + * + * + * @return a new object of class 'EBuilt In Module'. + * @generated + */ + EBuiltInModule createEBuiltInModule(); + + /** + * Returns a new object of class 'EJar File'. + * + * + * @return a new object of class 'EJar File'. + * @generated + */ + EJarFile createEJarFile(); + + /** + * Returns a new object of class 'EFile'. + * + * + * @return a new object of class 'EFile'. + * @generated + */ + EFile createEFile(); + + /** + * Returns a new object of class 'EClass File'. + * + * + * @return a new object of class 'EClass File'. + * @generated + */ + EClassFile createEClassFile(); + + /** + * Returns a new object of class 'ESource File'. + * + * + * @return a new object of class 'ESource File'. + * @generated + */ + ESourceFile createESourceFile(); + + /** + * Returns a new object of class 'EClasspath'. + * + * + * @return a new object of class 'EClasspath'. + * @generated + */ + EClasspath createEClasspath(); + + /** + * Returns the package supported by this factory. + * + * + * @return the package supported by this factory. + * @generated + */ + JavaScopePackage getJavaScopePackage(); + +} //JavaScopeFactory diff --git a/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/JavaScopePackage.java b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/JavaScopePackage.java new file mode 100644 index 000000000..dc41814e4 --- /dev/null +++ b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/JavaScopePackage.java @@ -0,0 +1,741 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java.scope; + +import org.eclipse.emf.ecore.EAttribute; +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EEnum; +import org.eclipse.emf.ecore.EPackage; +import org.eclipse.emf.ecore.EReference; + +/** + * + * The Package for the model. + * It contains accessors for the meta objects to represent + *
                                + *
                              • each class,
                              • + *
                              • each feature of each class,
                              • + *
                              • each enum,
                              • + *
                              • and each data type
                              • + *
                              + * + * @see com.ibm.wala.ecore.java.scope.JavaScopeFactory + * @model kind="package" + * @generated + */ +public interface JavaScopePackage extends EPackage { + /** + * The package name. + * + * + * @generated + */ + String eNAME = "scope"; + + /** + * The package namespace URI. + * + * + * @generated + */ + String eNS_URI = "http:///com/ibm/wala/wala.ecore.java.scope"; + + /** + * The package namespace name. + * + * + * @generated + */ + String eNS_PREFIX = "com.ibm.wala.java.scope"; + + /** + * The singleton instance of the package. + * + * + * @generated + */ + JavaScopePackage eINSTANCE = com.ibm.wala.ecore.java.scope.impl.JavaScopePackageImpl.init(); + + /** + * The meta object id for the '{@link com.ibm.wala.ecore.java.scope.impl.EJavaAnalysisScopeImpl EJava Analysis Scope}' class. + * + * + * @see com.ibm.wala.ecore.java.scope.impl.EJavaAnalysisScopeImpl + * @see com.ibm.wala.ecore.java.scope.impl.JavaScopePackageImpl#getEJavaAnalysisScope() + * @generated + */ + int EJAVA_ANALYSIS_SCOPE = 0; + + /** + * The feature id for the 'Loaders' containment reference list. + * + * + * @generated + * @ordered + */ + int EJAVA_ANALYSIS_SCOPE__LOADERS = 0; + + /** + * The feature id for the 'Exclusion File Name' attribute. + * + * + * @generated + * @ordered + */ + int EJAVA_ANALYSIS_SCOPE__EXCLUSION_FILE_NAME = 1; + + /** + * The number of structural features of the 'EJava Analysis Scope' class. + * + * + * @generated + * @ordered + */ + int EJAVA_ANALYSIS_SCOPE_FEATURE_COUNT = 2; + + /** + * The meta object id for the '{@link com.ibm.wala.ecore.java.scope.impl.EClassLoaderImpl EClass Loader}' class. + * + * + * @see com.ibm.wala.ecore.java.scope.impl.EClassLoaderImpl + * @see com.ibm.wala.ecore.java.scope.impl.JavaScopePackageImpl#getEClassLoader() + * @generated + */ + int ECLASS_LOADER = 1; + + /** + * The feature id for the 'Modules' containment reference list. + * + * + * @generated + * @ordered + */ + int ECLASS_LOADER__MODULES = 0; + + /** + * The feature id for the 'Loader Name' attribute. + * + * + * @generated + * @ordered + */ + int ECLASS_LOADER__LOADER_NAME = 1; + + /** + * The number of structural features of the 'EClass Loader' class. + * + * + * @generated + * @ordered + */ + int ECLASS_LOADER_FEATURE_COUNT = 2; + + /** + * The meta object id for the '{@link com.ibm.wala.ecore.java.scope.EModule EModule}' class. + * + * + * @see com.ibm.wala.ecore.java.scope.EModule + * @see com.ibm.wala.ecore.java.scope.impl.JavaScopePackageImpl#getEModule() + * @generated + */ + int EMODULE = 2; + + /** + * The number of structural features of the 'EModule' class. + * + * + * @generated + * @ordered + */ + int EMODULE_FEATURE_COUNT = 0; + + /** + * The meta object id for the '{@link com.ibm.wala.ecore.java.scope.impl.EBuiltInModuleImpl EBuilt In Module}' class. + * + * + * @see com.ibm.wala.ecore.java.scope.impl.EBuiltInModuleImpl + * @see com.ibm.wala.ecore.java.scope.impl.JavaScopePackageImpl#getEBuiltInModule() + * @generated + */ + int EBUILT_IN_MODULE = 3; + + /** + * The feature id for the 'Id' attribute. + * + * + * @generated + * @ordered + */ + int EBUILT_IN_MODULE__ID = EMODULE_FEATURE_COUNT + 0; + + /** + * The number of structural features of the 'EBuilt In Module' class. + * + * + * @generated + * @ordered + */ + int EBUILT_IN_MODULE_FEATURE_COUNT = EMODULE_FEATURE_COUNT + 1; + + /** + * The meta object id for the '{@link com.ibm.wala.ecore.java.scope.impl.EJarFileImpl EJar File}' class. + * + * + * @see com.ibm.wala.ecore.java.scope.impl.EJarFileImpl + * @see com.ibm.wala.ecore.java.scope.impl.JavaScopePackageImpl#getEJarFile() + * @generated + */ + int EJAR_FILE = 4; + + /** + * The feature id for the 'Url' attribute. + * + * + * @generated + * @ordered + */ + int EJAR_FILE__URL = EMODULE_FEATURE_COUNT + 0; + + /** + * The number of structural features of the 'EJar File' class. + * + * + * @generated + * @ordered + */ + int EJAR_FILE_FEATURE_COUNT = EMODULE_FEATURE_COUNT + 1; + + /** + * The meta object id for the '{@link com.ibm.wala.ecore.java.scope.impl.EFileImpl EFile}' class. + * + * + * @see com.ibm.wala.ecore.java.scope.impl.EFileImpl + * @see com.ibm.wala.ecore.java.scope.impl.JavaScopePackageImpl#getEFile() + * @generated + */ + int EFILE = 5; + + /** + * The feature id for the 'Url' attribute. + * + * + * @generated + * @ordered + */ + int EFILE__URL = EMODULE_FEATURE_COUNT + 0; + + /** + * The number of structural features of the 'EFile' class. + * + * + * @generated + * @ordered + */ + int EFILE_FEATURE_COUNT = EMODULE_FEATURE_COUNT + 1; + + /** + * The meta object id for the '{@link com.ibm.wala.ecore.java.scope.impl.EClassFileImpl EClass File}' class. + * + * + * @see com.ibm.wala.ecore.java.scope.impl.EClassFileImpl + * @see com.ibm.wala.ecore.java.scope.impl.JavaScopePackageImpl#getEClassFile() + * @generated + */ + int ECLASS_FILE = 6; + + /** + * The feature id for the 'Url' attribute. + * + * + * @generated + * @ordered + */ + int ECLASS_FILE__URL = EFILE__URL; + + /** + * The number of structural features of the 'EClass File' class. + * + * + * @generated + * @ordered + */ + int ECLASS_FILE_FEATURE_COUNT = EFILE_FEATURE_COUNT + 0; + + /** + * The meta object id for the '{@link com.ibm.wala.ecore.java.scope.impl.ESourceFileImpl ESource File}' class. + * + * + * @see com.ibm.wala.ecore.java.scope.impl.ESourceFileImpl + * @see com.ibm.wala.ecore.java.scope.impl.JavaScopePackageImpl#getESourceFile() + * @generated + */ + int ESOURCE_FILE = 7; + + /** + * The feature id for the 'Url' attribute. + * + * + * @generated + * @ordered + */ + int ESOURCE_FILE__URL = EFILE__URL; + + /** + * The number of structural features of the 'ESource File' class. + * + * + * @generated + * @ordered + */ + int ESOURCE_FILE_FEATURE_COUNT = EFILE_FEATURE_COUNT + 0; + + /** + * The meta object id for the '{@link com.ibm.wala.ecore.java.scope.impl.EClasspathImpl EClasspath}' class. + * + * + * @see com.ibm.wala.ecore.java.scope.impl.EClasspathImpl + * @see com.ibm.wala.ecore.java.scope.impl.JavaScopePackageImpl#getEClasspath() + * @generated + */ + int ECLASSPATH = 8; + + /** + * The feature id for the 'String' attribute. + * + * + * @generated + * @ordered + */ + int ECLASSPATH__STRING = 0; + + /** + * The number of structural features of the 'EClasspath' class. + * + * + * @generated + * @ordered + */ + int ECLASSPATH_FEATURE_COUNT = 1; + + /** + * The meta object id for the '{@link com.ibm.wala.ecore.java.scope.EBuiltInResource EBuilt In Resource}' enum. + * + * + * @see com.ibm.wala.ecore.java.scope.EBuiltInResource + * @see com.ibm.wala.ecore.java.scope.impl.JavaScopePackageImpl#getEBuiltInResource() + * @generated + */ + int EBUILT_IN_RESOURCE = 9; + + /** + * The meta object id for the '{@link com.ibm.wala.ecore.java.scope.EStandardClassLoader EStandard Class Loader}' enum. + * + * + * @see com.ibm.wala.ecore.java.scope.EStandardClassLoader + * @see com.ibm.wala.ecore.java.scope.impl.JavaScopePackageImpl#getEStandardClassLoader() + * @generated + */ + int ESTANDARD_CLASS_LOADER = 10; + + + /** + * Returns the meta object for class '{@link com.ibm.wala.ecore.java.scope.EJavaAnalysisScope EJava Analysis Scope}'. + * + * + * @return the meta object for class 'EJava Analysis Scope'. + * @see com.ibm.wala.ecore.java.scope.EJavaAnalysisScope + * @generated + */ + EClass getEJavaAnalysisScope(); + + /** + * Returns the meta object for the containment reference list '{@link com.ibm.wala.ecore.java.scope.EJavaAnalysisScope#getLoaders Loaders}'. + * + * + * @return the meta object for the containment reference list 'Loaders'. + * @see com.ibm.wala.ecore.java.scope.EJavaAnalysisScope#getLoaders() + * @see #getEJavaAnalysisScope() + * @generated + */ + EReference getEJavaAnalysisScope_Loaders(); + + /** + * Returns the meta object for the attribute '{@link com.ibm.wala.ecore.java.scope.EJavaAnalysisScope#getExclusionFileName Exclusion File Name}'. + * + * + * @return the meta object for the attribute 'Exclusion File Name'. + * @see com.ibm.wala.ecore.java.scope.EJavaAnalysisScope#getExclusionFileName() + * @see #getEJavaAnalysisScope() + * @generated + */ + EAttribute getEJavaAnalysisScope_ExclusionFileName(); + + /** + * Returns the meta object for class '{@link com.ibm.wala.ecore.java.scope.EClassLoader EClass Loader}'. + * + * + * @return the meta object for class 'EClass Loader'. + * @see com.ibm.wala.ecore.java.scope.EClassLoader + * @generated + */ + EClass getEClassLoader(); + + /** + * Returns the meta object for the containment reference list '{@link com.ibm.wala.ecore.java.scope.EClassLoader#getModules Modules}'. + * + * + * @return the meta object for the containment reference list 'Modules'. + * @see com.ibm.wala.ecore.java.scope.EClassLoader#getModules() + * @see #getEClassLoader() + * @generated + */ + EReference getEClassLoader_Modules(); + + /** + * Returns the meta object for the attribute '{@link com.ibm.wala.ecore.java.scope.EClassLoader#getLoaderName Loader Name}'. + * + * + * @return the meta object for the attribute 'Loader Name'. + * @see com.ibm.wala.ecore.java.scope.EClassLoader#getLoaderName() + * @see #getEClassLoader() + * @generated + */ + EAttribute getEClassLoader_LoaderName(); + + /** + * Returns the meta object for class '{@link com.ibm.wala.ecore.java.scope.EModule EModule}'. + * + * + * @return the meta object for class 'EModule'. + * @see com.ibm.wala.ecore.java.scope.EModule + * @generated + */ + EClass getEModule(); + + /** + * Returns the meta object for class '{@link com.ibm.wala.ecore.java.scope.EBuiltInModule EBuilt In Module}'. + * + * + * @return the meta object for class 'EBuilt In Module'. + * @see com.ibm.wala.ecore.java.scope.EBuiltInModule + * @generated + */ + EClass getEBuiltInModule(); + + /** + * Returns the meta object for the attribute '{@link com.ibm.wala.ecore.java.scope.EBuiltInModule#getId Id}'. + * + * + * @return the meta object for the attribute 'Id'. + * @see com.ibm.wala.ecore.java.scope.EBuiltInModule#getId() + * @see #getEBuiltInModule() + * @generated + */ + EAttribute getEBuiltInModule_Id(); + + /** + * Returns the meta object for class '{@link com.ibm.wala.ecore.java.scope.EJarFile EJar File}'. + * + * + * @return the meta object for class 'EJar File'. + * @see com.ibm.wala.ecore.java.scope.EJarFile + * @generated + */ + EClass getEJarFile(); + + /** + * Returns the meta object for the attribute '{@link com.ibm.wala.ecore.java.scope.EJarFile#getUrl Url}'. + * + * + * @return the meta object for the attribute 'Url'. + * @see com.ibm.wala.ecore.java.scope.EJarFile#getUrl() + * @see #getEJarFile() + * @generated + */ + EAttribute getEJarFile_Url(); + + /** + * Returns the meta object for class '{@link com.ibm.wala.ecore.java.scope.EFile EFile}'. + * + * + * @return the meta object for class 'EFile'. + * @see com.ibm.wala.ecore.java.scope.EFile + * @generated + */ + EClass getEFile(); + + /** + * Returns the meta object for the attribute '{@link com.ibm.wala.ecore.java.scope.EFile#getUrl Url}'. + * + * + * @return the meta object for the attribute 'Url'. + * @see com.ibm.wala.ecore.java.scope.EFile#getUrl() + * @see #getEFile() + * @generated + */ + EAttribute getEFile_Url(); + + /** + * Returns the meta object for class '{@link com.ibm.wala.ecore.java.scope.EClassFile EClass File}'. + * + * + * @return the meta object for class 'EClass File'. + * @see com.ibm.wala.ecore.java.scope.EClassFile + * @generated + */ + EClass getEClassFile(); + + /** + * Returns the meta object for class '{@link com.ibm.wala.ecore.java.scope.ESourceFile ESource File}'. + * + * + * @return the meta object for class 'ESource File'. + * @see com.ibm.wala.ecore.java.scope.ESourceFile + * @generated + */ + EClass getESourceFile(); + + /** + * Returns the meta object for class '{@link com.ibm.wala.ecore.java.scope.EClasspath EClasspath}'. + * + * + * @return the meta object for class 'EClasspath'. + * @see com.ibm.wala.ecore.java.scope.EClasspath + * @generated + */ + EClass getEClasspath(); + + /** + * Returns the meta object for the attribute '{@link com.ibm.wala.ecore.java.scope.EClasspath#getString String}'. + * + * + * @return the meta object for the attribute 'String'. + * @see com.ibm.wala.ecore.java.scope.EClasspath#getString() + * @see #getEClasspath() + * @generated + */ + EAttribute getEClasspath_String(); + + /** + * Returns the meta object for enum '{@link com.ibm.wala.ecore.java.scope.EBuiltInResource EBuilt In Resource}'. + * + * + * @return the meta object for enum 'EBuilt In Resource'. + * @see com.ibm.wala.ecore.java.scope.EBuiltInResource + * @generated + */ + EEnum getEBuiltInResource(); + + /** + * Returns the meta object for enum '{@link com.ibm.wala.ecore.java.scope.EStandardClassLoader EStandard Class Loader}'. + * + * + * @return the meta object for enum 'EStandard Class Loader'. + * @see com.ibm.wala.ecore.java.scope.EStandardClassLoader + * @generated + */ + EEnum getEStandardClassLoader(); + + /** + * Returns the factory that creates the instances of the model. + * + * + * @return the factory that creates the instances of the model. + * @generated + */ + JavaScopeFactory getJavaScopeFactory(); + + /** + * + * Defines literals for the meta objects that represent + *
                                + *
                              • each class,
                              • + *
                              • each feature of each class,
                              • + *
                              • each enum,
                              • + *
                              • and each data type
                              • + *
                              + * + * @generated + */ + interface Literals { + /** + * The meta object literal for the '{@link com.ibm.wala.ecore.java.scope.impl.EJavaAnalysisScopeImpl EJava Analysis Scope}' class. + * + * + * @see com.ibm.wala.ecore.java.scope.impl.EJavaAnalysisScopeImpl + * @see com.ibm.wala.ecore.java.scope.impl.JavaScopePackageImpl#getEJavaAnalysisScope() + * @generated + */ + EClass EJAVA_ANALYSIS_SCOPE = eINSTANCE.getEJavaAnalysisScope(); + + /** + * The meta object literal for the 'Loaders' containment reference list feature. + * + * + * @generated + */ + EReference EJAVA_ANALYSIS_SCOPE__LOADERS = eINSTANCE.getEJavaAnalysisScope_Loaders(); + + /** + * The meta object literal for the 'Exclusion File Name' attribute feature. + * + * + * @generated + */ + EAttribute EJAVA_ANALYSIS_SCOPE__EXCLUSION_FILE_NAME = eINSTANCE.getEJavaAnalysisScope_ExclusionFileName(); + + /** + * The meta object literal for the '{@link com.ibm.wala.ecore.java.scope.impl.EClassLoaderImpl EClass Loader}' class. + * + * + * @see com.ibm.wala.ecore.java.scope.impl.EClassLoaderImpl + * @see com.ibm.wala.ecore.java.scope.impl.JavaScopePackageImpl#getEClassLoader() + * @generated + */ + EClass ECLASS_LOADER = eINSTANCE.getEClassLoader(); + + /** + * The meta object literal for the 'Modules' containment reference list feature. + * + * + * @generated + */ + EReference ECLASS_LOADER__MODULES = eINSTANCE.getEClassLoader_Modules(); + + /** + * The meta object literal for the 'Loader Name' attribute feature. + * + * + * @generated + */ + EAttribute ECLASS_LOADER__LOADER_NAME = eINSTANCE.getEClassLoader_LoaderName(); + + /** + * The meta object literal for the '{@link com.ibm.wala.ecore.java.scope.EModule EModule}' class. + * + * + * @see com.ibm.wala.ecore.java.scope.EModule + * @see com.ibm.wala.ecore.java.scope.impl.JavaScopePackageImpl#getEModule() + * @generated + */ + EClass EMODULE = eINSTANCE.getEModule(); + + /** + * The meta object literal for the '{@link com.ibm.wala.ecore.java.scope.impl.EBuiltInModuleImpl EBuilt In Module}' class. + * + * + * @see com.ibm.wala.ecore.java.scope.impl.EBuiltInModuleImpl + * @see com.ibm.wala.ecore.java.scope.impl.JavaScopePackageImpl#getEBuiltInModule() + * @generated + */ + EClass EBUILT_IN_MODULE = eINSTANCE.getEBuiltInModule(); + + /** + * The meta object literal for the 'Id' attribute feature. + * + * + * @generated + */ + EAttribute EBUILT_IN_MODULE__ID = eINSTANCE.getEBuiltInModule_Id(); + + /** + * The meta object literal for the '{@link com.ibm.wala.ecore.java.scope.impl.EJarFileImpl EJar File}' class. + * + * + * @see com.ibm.wala.ecore.java.scope.impl.EJarFileImpl + * @see com.ibm.wala.ecore.java.scope.impl.JavaScopePackageImpl#getEJarFile() + * @generated + */ + EClass EJAR_FILE = eINSTANCE.getEJarFile(); + + /** + * The meta object literal for the 'Url' attribute feature. + * + * + * @generated + */ + EAttribute EJAR_FILE__URL = eINSTANCE.getEJarFile_Url(); + + /** + * The meta object literal for the '{@link com.ibm.wala.ecore.java.scope.impl.EFileImpl EFile}' class. + * + * + * @see com.ibm.wala.ecore.java.scope.impl.EFileImpl + * @see com.ibm.wala.ecore.java.scope.impl.JavaScopePackageImpl#getEFile() + * @generated + */ + EClass EFILE = eINSTANCE.getEFile(); + + /** + * The meta object literal for the 'Url' attribute feature. + * + * + * @generated + */ + EAttribute EFILE__URL = eINSTANCE.getEFile_Url(); + + /** + * The meta object literal for the '{@link com.ibm.wala.ecore.java.scope.impl.EClassFileImpl EClass File}' class. + * + * + * @see com.ibm.wala.ecore.java.scope.impl.EClassFileImpl + * @see com.ibm.wala.ecore.java.scope.impl.JavaScopePackageImpl#getEClassFile() + * @generated + */ + EClass ECLASS_FILE = eINSTANCE.getEClassFile(); + + /** + * The meta object literal for the '{@link com.ibm.wala.ecore.java.scope.impl.ESourceFileImpl ESource File}' class. + * + * + * @see com.ibm.wala.ecore.java.scope.impl.ESourceFileImpl + * @see com.ibm.wala.ecore.java.scope.impl.JavaScopePackageImpl#getESourceFile() + * @generated + */ + EClass ESOURCE_FILE = eINSTANCE.getESourceFile(); + + /** + * The meta object literal for the '{@link com.ibm.wala.ecore.java.scope.impl.EClasspathImpl EClasspath}' class. + * + * + * @see com.ibm.wala.ecore.java.scope.impl.EClasspathImpl + * @see com.ibm.wala.ecore.java.scope.impl.JavaScopePackageImpl#getEClasspath() + * @generated + */ + EClass ECLASSPATH = eINSTANCE.getEClasspath(); + + /** + * The meta object literal for the 'String' attribute feature. + * + * + * @generated + */ + EAttribute ECLASSPATH__STRING = eINSTANCE.getEClasspath_String(); + + /** + * The meta object literal for the '{@link com.ibm.wala.ecore.java.scope.EBuiltInResource EBuilt In Resource}' enum. + * + * + * @see com.ibm.wala.ecore.java.scope.EBuiltInResource + * @see com.ibm.wala.ecore.java.scope.impl.JavaScopePackageImpl#getEBuiltInResource() + * @generated + */ + EEnum EBUILT_IN_RESOURCE = eINSTANCE.getEBuiltInResource(); + + /** + * The meta object literal for the '{@link com.ibm.wala.ecore.java.scope.EStandardClassLoader EStandard Class Loader}' enum. + * + * + * @see com.ibm.wala.ecore.java.scope.EStandardClassLoader + * @see com.ibm.wala.ecore.java.scope.impl.JavaScopePackageImpl#getEStandardClassLoader() + * @generated + */ + EEnum ESTANDARD_CLASS_LOADER = eINSTANCE.getEStandardClassLoader(); + + } + +} //JavaScopePackage diff --git a/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/impl/EBuiltInModuleImpl.java b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/impl/EBuiltInModuleImpl.java new file mode 100644 index 000000000..993ab1dfe --- /dev/null +++ b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/impl/EBuiltInModuleImpl.java @@ -0,0 +1,162 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java.scope.impl; + +import com.ibm.wala.ecore.java.scope.EBuiltInModule; +import com.ibm.wala.ecore.java.scope.EBuiltInResource; +import com.ibm.wala.ecore.java.scope.JavaScopePackage; + +import org.eclipse.emf.common.notify.Notification; + +import org.eclipse.emf.ecore.EClass; + +import org.eclipse.emf.ecore.impl.ENotificationImpl; +import org.eclipse.emf.ecore.impl.EObjectImpl; + +/** + * + * An implementation of the model object 'EBuilt In Module'. + * + *

                              + * The following features are implemented: + *

                                + *
                              • {@link com.ibm.wala.ecore.java.scope.impl.EBuiltInModuleImpl#getId Id}
                              • + *
                              + *

                              + * + * @generated + */ +public class EBuiltInModuleImpl extends EObjectImpl implements EBuiltInModule { + /** + * The default value of the '{@link #getId() Id}' attribute. + * + * + * @see #getId() + * @generated + * @ordered + */ + protected static final EBuiltInResource ID_EDEFAULT = EBuiltInResource.DEFAULT_J2SE_LIBS_LITERAL; + + /** + * The cached value of the '{@link #getId() Id}' attribute. + * + * + * @see #getId() + * @generated + * @ordered + */ + protected EBuiltInResource id = ID_EDEFAULT; + + /** + * + * + * @generated + */ + protected EBuiltInModuleImpl() { + super(); + } + + /** + * + * + * @generated + */ + protected EClass eStaticClass() { + return JavaScopePackage.Literals.EBUILT_IN_MODULE; + } + + /** + * + * + * @generated + */ + public EBuiltInResource getId() { + return id; + } + + /** + * + * + * @generated + */ + public void setId(EBuiltInResource newId) { + EBuiltInResource oldId = id; + id = newId == null ? ID_EDEFAULT : newId; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, JavaScopePackage.EBUILT_IN_MODULE__ID, oldId, id)); + } + + /** + * + * + * @generated + */ + public Object eGet(int featureID, boolean resolve, boolean coreType) { + switch (featureID) { + case JavaScopePackage.EBUILT_IN_MODULE__ID: + return getId(); + } + return super.eGet(featureID, resolve, coreType); + } + + /** + * + * + * @generated + */ + public void eSet(int featureID, Object newValue) { + switch (featureID) { + case JavaScopePackage.EBUILT_IN_MODULE__ID: + setId((EBuiltInResource)newValue); + return; + } + super.eSet(featureID, newValue); + } + + /** + * + * + * @generated + */ + public void eUnset(int featureID) { + switch (featureID) { + case JavaScopePackage.EBUILT_IN_MODULE__ID: + setId(ID_EDEFAULT); + return; + } + super.eUnset(featureID); + } + + /** + * + * + * @generated + */ + public boolean eIsSet(int featureID) { + switch (featureID) { + case JavaScopePackage.EBUILT_IN_MODULE__ID: + return id != ID_EDEFAULT; + } + return super.eIsSet(featureID); + } + + /** + * + * + * @generated + */ + public String toString() { + if (eIsProxy()) return super.toString(); + + StringBuffer result = new StringBuffer(super.toString()); + result.append(" (id: "); + result.append(id); + result.append(')'); + return result.toString(); + } + +} //EBuiltInModuleImpl \ No newline at end of file diff --git a/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/impl/EClassFileImpl.java b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/impl/EClassFileImpl.java new file mode 100644 index 000000000..686a024af --- /dev/null +++ b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/impl/EClassFileImpl.java @@ -0,0 +1,42 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java.scope.impl; + +import com.ibm.wala.ecore.java.scope.EClassFile; +import com.ibm.wala.ecore.java.scope.JavaScopePackage; + +import org.eclipse.emf.ecore.EClass; + +/** + * + * An implementation of the model object 'EClass File'. + * + *

                              + *

                              + * + * @generated + */ +public class EClassFileImpl extends EFileImpl implements EClassFile { + /** + * + * + * @generated + */ + protected EClassFileImpl() { + super(); + } + + /** + * + * + * @generated + */ + protected EClass eStaticClass() { + return JavaScopePackage.Literals.ECLASS_FILE; + } + +} //EClassFileImpl \ No newline at end of file diff --git a/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/impl/EClassLoaderImpl.java b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/impl/EClassLoaderImpl.java new file mode 100644 index 000000000..8557f8320 --- /dev/null +++ b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/impl/EClassLoaderImpl.java @@ -0,0 +1,218 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java.scope.impl; + +import com.ibm.wala.ecore.java.scope.EClassLoader; +import com.ibm.wala.ecore.java.scope.EModule; +import com.ibm.wala.ecore.java.scope.JavaScopePackage; + +import java.util.Collection; + +import org.eclipse.emf.common.notify.Notification; +import org.eclipse.emf.common.notify.NotificationChain; + +import org.eclipse.emf.common.util.EList; + +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.InternalEObject; + +import org.eclipse.emf.ecore.impl.ENotificationImpl; +import org.eclipse.emf.ecore.impl.EObjectImpl; + +import org.eclipse.emf.ecore.util.EObjectContainmentEList; +import org.eclipse.emf.ecore.util.InternalEList; + +/** + * + * An implementation of the model object 'EClass Loader'. + * + *

                              + * The following features are implemented: + *

                                + *
                              • {@link com.ibm.wala.ecore.java.scope.impl.EClassLoaderImpl#getModules Modules}
                              • + *
                              • {@link com.ibm.wala.ecore.java.scope.impl.EClassLoaderImpl#getLoaderName Loader Name}
                              • + *
                              + *

                              + * + * @generated + */ +public class EClassLoaderImpl extends EObjectImpl implements EClassLoader { + /** + * The cached value of the '{@link #getModules() Modules}' containment reference list. + * + * + * @see #getModules() + * @generated + * @ordered + */ + protected EList modules = null; + + /** + * The default value of the '{@link #getLoaderName() Loader Name}' attribute. + * + * + * @see #getLoaderName() + * @generated + * @ordered + */ + protected static final String LOADER_NAME_EDEFAULT = null; + + /** + * The cached value of the '{@link #getLoaderName() Loader Name}' attribute. + * + * + * @see #getLoaderName() + * @generated + * @ordered + */ + protected String loaderName = LOADER_NAME_EDEFAULT; + + /** + * + * + * @generated + */ + protected EClassLoaderImpl() { + super(); + } + + /** + * + * + * @generated + */ + protected EClass eStaticClass() { + return JavaScopePackage.Literals.ECLASS_LOADER; + } + + /** + * + * + * @generated + */ + public EList getModules() { + if (modules == null) { + modules = new EObjectContainmentEList(EModule.class, this, JavaScopePackage.ECLASS_LOADER__MODULES); + } + return modules; + } + + /** + * + * + * @generated + */ + public String getLoaderName() { + return loaderName; + } + + /** + * + * + * @generated + */ + public void setLoaderName(String newLoaderName) { + String oldLoaderName = loaderName; + loaderName = newLoaderName; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, JavaScopePackage.ECLASS_LOADER__LOADER_NAME, oldLoaderName, loaderName)); + } + + /** + * + * + * @generated + */ + public NotificationChain eInverseRemove(InternalEObject otherEnd, int featureID, NotificationChain msgs) { + switch (featureID) { + case JavaScopePackage.ECLASS_LOADER__MODULES: + return ((InternalEList)getModules()).basicRemove(otherEnd, msgs); + } + return super.eInverseRemove(otherEnd, featureID, msgs); + } + + /** + * + * + * @generated + */ + public Object eGet(int featureID, boolean resolve, boolean coreType) { + switch (featureID) { + case JavaScopePackage.ECLASS_LOADER__MODULES: + return getModules(); + case JavaScopePackage.ECLASS_LOADER__LOADER_NAME: + return getLoaderName(); + } + return super.eGet(featureID, resolve, coreType); + } + + /** + * + * + * @generated + */ + public void eSet(int featureID, Object newValue) { + switch (featureID) { + case JavaScopePackage.ECLASS_LOADER__MODULES: + getModules().clear(); + getModules().addAll((Collection)newValue); + return; + case JavaScopePackage.ECLASS_LOADER__LOADER_NAME: + setLoaderName((String)newValue); + return; + } + super.eSet(featureID, newValue); + } + + /** + * + * + * @generated + */ + public void eUnset(int featureID) { + switch (featureID) { + case JavaScopePackage.ECLASS_LOADER__MODULES: + getModules().clear(); + return; + case JavaScopePackage.ECLASS_LOADER__LOADER_NAME: + setLoaderName(LOADER_NAME_EDEFAULT); + return; + } + super.eUnset(featureID); + } + + /** + * + * + * @generated + */ + public boolean eIsSet(int featureID) { + switch (featureID) { + case JavaScopePackage.ECLASS_LOADER__MODULES: + return modules != null && !modules.isEmpty(); + case JavaScopePackage.ECLASS_LOADER__LOADER_NAME: + return LOADER_NAME_EDEFAULT == null ? loaderName != null : !LOADER_NAME_EDEFAULT.equals(loaderName); + } + return super.eIsSet(featureID); + } + + /** + * + * + * @generated + */ + public String toString() { + if (eIsProxy()) return super.toString(); + + StringBuffer result = new StringBuffer(super.toString()); + result.append(" (loaderName: "); + result.append(loaderName); + result.append(')'); + return result.toString(); + } + +} //EClassLoaderImpl \ No newline at end of file diff --git a/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/impl/EClasspathImpl.java b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/impl/EClasspathImpl.java new file mode 100644 index 000000000..b2f0e812b --- /dev/null +++ b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/impl/EClasspathImpl.java @@ -0,0 +1,161 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java.scope.impl; + +import com.ibm.wala.ecore.java.scope.EClasspath; +import com.ibm.wala.ecore.java.scope.JavaScopePackage; + +import org.eclipse.emf.common.notify.Notification; + +import org.eclipse.emf.ecore.EClass; + +import org.eclipse.emf.ecore.impl.ENotificationImpl; +import org.eclipse.emf.ecore.impl.EObjectImpl; + +/** + * + * An implementation of the model object 'EClasspath'. + * + *

                              + * The following features are implemented: + *

                                + *
                              • {@link com.ibm.wala.ecore.java.scope.impl.EClasspathImpl#getString String}
                              • + *
                              + *

                              + * + * @generated + */ +public class EClasspathImpl extends EObjectImpl implements EClasspath { + /** + * The default value of the '{@link #getString() String}' attribute. + * + * + * @see #getString() + * @generated + * @ordered + */ + protected static final String STRING_EDEFAULT = null; + + /** + * The cached value of the '{@link #getString() String}' attribute. + * + * + * @see #getString() + * @generated + * @ordered + */ + protected String string = STRING_EDEFAULT; + + /** + * + * + * @generated + */ + protected EClasspathImpl() { + super(); + } + + /** + * + * + * @generated + */ + protected EClass eStaticClass() { + return JavaScopePackage.Literals.ECLASSPATH; + } + + /** + * + * + * @generated + */ + public String getString() { + return string; + } + + /** + * + * + * @generated + */ + public void setString(String newString) { + String oldString = string; + string = newString; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, JavaScopePackage.ECLASSPATH__STRING, oldString, string)); + } + + /** + * + * + * @generated + */ + public Object eGet(int featureID, boolean resolve, boolean coreType) { + switch (featureID) { + case JavaScopePackage.ECLASSPATH__STRING: + return getString(); + } + return super.eGet(featureID, resolve, coreType); + } + + /** + * + * + * @generated + */ + public void eSet(int featureID, Object newValue) { + switch (featureID) { + case JavaScopePackage.ECLASSPATH__STRING: + setString((String)newValue); + return; + } + super.eSet(featureID, newValue); + } + + /** + * + * + * @generated + */ + public void eUnset(int featureID) { + switch (featureID) { + case JavaScopePackage.ECLASSPATH__STRING: + setString(STRING_EDEFAULT); + return; + } + super.eUnset(featureID); + } + + /** + * + * + * @generated + */ + public boolean eIsSet(int featureID) { + switch (featureID) { + case JavaScopePackage.ECLASSPATH__STRING: + return STRING_EDEFAULT == null ? string != null : !STRING_EDEFAULT.equals(string); + } + return super.eIsSet(featureID); + } + + /** + * + * + * @generated + */ + public String toString() { + if (eIsProxy()) return super.toString(); + + StringBuffer result = new StringBuffer(super.toString()); + result.append(" (string: "); + result.append(string); + result.append(')'); + return result.toString(); + } + +} //EClasspathImpl \ No newline at end of file diff --git a/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/impl/EFileImpl.java b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/impl/EFileImpl.java new file mode 100644 index 000000000..e83296b1f --- /dev/null +++ b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/impl/EFileImpl.java @@ -0,0 +1,161 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java.scope.impl; + +import com.ibm.wala.ecore.java.scope.EFile; +import com.ibm.wala.ecore.java.scope.JavaScopePackage; + +import org.eclipse.emf.common.notify.Notification; + +import org.eclipse.emf.ecore.EClass; + +import org.eclipse.emf.ecore.impl.ENotificationImpl; +import org.eclipse.emf.ecore.impl.EObjectImpl; + +/** + * + * An implementation of the model object 'EFile'. + * + *

                              + * The following features are implemented: + *

                                + *
                              • {@link com.ibm.wala.ecore.java.scope.impl.EFileImpl#getUrl Url}
                              • + *
                              + *

                              + * + * @generated + */ +public class EFileImpl extends EObjectImpl implements EFile { + /** + * The default value of the '{@link #getUrl() Url}' attribute. + * + * + * @see #getUrl() + * @generated + * @ordered + */ + protected static final String URL_EDEFAULT = null; + + /** + * The cached value of the '{@link #getUrl() Url}' attribute. + * + * + * @see #getUrl() + * @generated + * @ordered + */ + protected String url = URL_EDEFAULT; + + /** + * + * + * @generated + */ + protected EFileImpl() { + super(); + } + + /** + * + * + * @generated + */ + protected EClass eStaticClass() { + return JavaScopePackage.Literals.EFILE; + } + + /** + * + * + * @generated + */ + public String getUrl() { + return url; + } + + /** + * + * + * @generated + */ + public void setUrl(String newUrl) { + String oldUrl = url; + url = newUrl; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, JavaScopePackage.EFILE__URL, oldUrl, url)); + } + + /** + * + * + * @generated + */ + public Object eGet(int featureID, boolean resolve, boolean coreType) { + switch (featureID) { + case JavaScopePackage.EFILE__URL: + return getUrl(); + } + return super.eGet(featureID, resolve, coreType); + } + + /** + * + * + * @generated + */ + public void eSet(int featureID, Object newValue) { + switch (featureID) { + case JavaScopePackage.EFILE__URL: + setUrl((String)newValue); + return; + } + super.eSet(featureID, newValue); + } + + /** + * + * + * @generated + */ + public void eUnset(int featureID) { + switch (featureID) { + case JavaScopePackage.EFILE__URL: + setUrl(URL_EDEFAULT); + return; + } + super.eUnset(featureID); + } + + /** + * + * + * @generated + */ + public boolean eIsSet(int featureID) { + switch (featureID) { + case JavaScopePackage.EFILE__URL: + return URL_EDEFAULT == null ? url != null : !URL_EDEFAULT.equals(url); + } + return super.eIsSet(featureID); + } + + /** + * + * + * @generated + */ + public String toString() { + if (eIsProxy()) return super.toString(); + + StringBuffer result = new StringBuffer(super.toString()); + result.append(" (url: "); + result.append(url); + result.append(')'); + return result.toString(); + } + +} //EFileImpl \ No newline at end of file diff --git a/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/impl/EJarFileImpl.java b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/impl/EJarFileImpl.java new file mode 100644 index 000000000..b15d5f695 --- /dev/null +++ b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/impl/EJarFileImpl.java @@ -0,0 +1,161 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java.scope.impl; + +import com.ibm.wala.ecore.java.scope.EJarFile; +import com.ibm.wala.ecore.java.scope.JavaScopePackage; + +import org.eclipse.emf.common.notify.Notification; + +import org.eclipse.emf.ecore.EClass; + +import org.eclipse.emf.ecore.impl.ENotificationImpl; +import org.eclipse.emf.ecore.impl.EObjectImpl; + +/** + * + * An implementation of the model object 'EJar File'. + * + *

                              + * The following features are implemented: + *

                                + *
                              • {@link com.ibm.wala.ecore.java.scope.impl.EJarFileImpl#getUrl Url}
                              • + *
                              + *

                              + * + * @generated + */ +public class EJarFileImpl extends EObjectImpl implements EJarFile { + /** + * The default value of the '{@link #getUrl() Url}' attribute. + * + * + * @see #getUrl() + * @generated + * @ordered + */ + protected static final String URL_EDEFAULT = null; + + /** + * The cached value of the '{@link #getUrl() Url}' attribute. + * + * + * @see #getUrl() + * @generated + * @ordered + */ + protected String url = URL_EDEFAULT; + + /** + * + * + * @generated + */ + protected EJarFileImpl() { + super(); + } + + /** + * + * + * @generated + */ + protected EClass eStaticClass() { + return JavaScopePackage.Literals.EJAR_FILE; + } + + /** + * + * + * @generated + */ + public String getUrl() { + return url; + } + + /** + * + * + * @generated + */ + public void setUrl(String newUrl) { + String oldUrl = url; + url = newUrl; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, JavaScopePackage.EJAR_FILE__URL, oldUrl, url)); + } + + /** + * + * + * @generated + */ + public Object eGet(int featureID, boolean resolve, boolean coreType) { + switch (featureID) { + case JavaScopePackage.EJAR_FILE__URL: + return getUrl(); + } + return super.eGet(featureID, resolve, coreType); + } + + /** + * + * + * @generated + */ + public void eSet(int featureID, Object newValue) { + switch (featureID) { + case JavaScopePackage.EJAR_FILE__URL: + setUrl((String)newValue); + return; + } + super.eSet(featureID, newValue); + } + + /** + * + * + * @generated + */ + public void eUnset(int featureID) { + switch (featureID) { + case JavaScopePackage.EJAR_FILE__URL: + setUrl(URL_EDEFAULT); + return; + } + super.eUnset(featureID); + } + + /** + * + * + * @generated + */ + public boolean eIsSet(int featureID) { + switch (featureID) { + case JavaScopePackage.EJAR_FILE__URL: + return URL_EDEFAULT == null ? url != null : !URL_EDEFAULT.equals(url); + } + return super.eIsSet(featureID); + } + + /** + * + * + * @generated + */ + public String toString() { + if (eIsProxy()) return super.toString(); + + StringBuffer result = new StringBuffer(super.toString()); + result.append(" (url: "); + result.append(url); + result.append(')'); + return result.toString(); + } + +} //EJarFileImpl \ No newline at end of file diff --git a/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/impl/EJavaAnalysisScopeImpl.java b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/impl/EJavaAnalysisScopeImpl.java new file mode 100644 index 000000000..c0c7dfb68 --- /dev/null +++ b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/impl/EJavaAnalysisScopeImpl.java @@ -0,0 +1,218 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java.scope.impl; + +import com.ibm.wala.ecore.java.scope.EClassLoader; +import com.ibm.wala.ecore.java.scope.EJavaAnalysisScope; +import com.ibm.wala.ecore.java.scope.JavaScopePackage; + +import java.util.Collection; + +import org.eclipse.emf.common.notify.Notification; +import org.eclipse.emf.common.notify.NotificationChain; + +import org.eclipse.emf.common.util.EList; + +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.InternalEObject; + +import org.eclipse.emf.ecore.impl.ENotificationImpl; +import org.eclipse.emf.ecore.impl.EObjectImpl; + +import org.eclipse.emf.ecore.util.EObjectContainmentEList; +import org.eclipse.emf.ecore.util.InternalEList; + +/** + * + * An implementation of the model object 'EJava Analysis Scope'. + * + *

                              + * The following features are implemented: + *

                                + *
                              • {@link com.ibm.wala.ecore.java.scope.impl.EJavaAnalysisScopeImpl#getLoaders Loaders}
                              • + *
                              • {@link com.ibm.wala.ecore.java.scope.impl.EJavaAnalysisScopeImpl#getExclusionFileName Exclusion File Name}
                              • + *
                              + *

                              + * + * @generated + */ +public class EJavaAnalysisScopeImpl extends EObjectImpl implements EJavaAnalysisScope { + /** + * The cached value of the '{@link #getLoaders() Loaders}' containment reference list. + * + * + * @see #getLoaders() + * @generated + * @ordered + */ + protected EList loaders = null; + + /** + * The default value of the '{@link #getExclusionFileName() Exclusion File Name}' attribute. + * + * + * @see #getExclusionFileName() + * @generated + * @ordered + */ + protected static final String EXCLUSION_FILE_NAME_EDEFAULT = null; + + /** + * The cached value of the '{@link #getExclusionFileName() Exclusion File Name}' attribute. + * + * + * @see #getExclusionFileName() + * @generated + * @ordered + */ + protected String exclusionFileName = EXCLUSION_FILE_NAME_EDEFAULT; + + /** + * + * + * @generated + */ + protected EJavaAnalysisScopeImpl() { + super(); + } + + /** + * + * + * @generated + */ + protected EClass eStaticClass() { + return JavaScopePackage.Literals.EJAVA_ANALYSIS_SCOPE; + } + + /** + * + * + * @generated + */ + public EList getLoaders() { + if (loaders == null) { + loaders = new EObjectContainmentEList(EClassLoader.class, this, JavaScopePackage.EJAVA_ANALYSIS_SCOPE__LOADERS); + } + return loaders; + } + + /** + * + * + * @generated + */ + public String getExclusionFileName() { + return exclusionFileName; + } + + /** + * + * + * @generated + */ + public void setExclusionFileName(String newExclusionFileName) { + String oldExclusionFileName = exclusionFileName; + exclusionFileName = newExclusionFileName; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, JavaScopePackage.EJAVA_ANALYSIS_SCOPE__EXCLUSION_FILE_NAME, oldExclusionFileName, exclusionFileName)); + } + + /** + * + * + * @generated + */ + public NotificationChain eInverseRemove(InternalEObject otherEnd, int featureID, NotificationChain msgs) { + switch (featureID) { + case JavaScopePackage.EJAVA_ANALYSIS_SCOPE__LOADERS: + return ((InternalEList)getLoaders()).basicRemove(otherEnd, msgs); + } + return super.eInverseRemove(otherEnd, featureID, msgs); + } + + /** + * + * + * @generated + */ + public Object eGet(int featureID, boolean resolve, boolean coreType) { + switch (featureID) { + case JavaScopePackage.EJAVA_ANALYSIS_SCOPE__LOADERS: + return getLoaders(); + case JavaScopePackage.EJAVA_ANALYSIS_SCOPE__EXCLUSION_FILE_NAME: + return getExclusionFileName(); + } + return super.eGet(featureID, resolve, coreType); + } + + /** + * + * + * @generated + */ + public void eSet(int featureID, Object newValue) { + switch (featureID) { + case JavaScopePackage.EJAVA_ANALYSIS_SCOPE__LOADERS: + getLoaders().clear(); + getLoaders().addAll((Collection)newValue); + return; + case JavaScopePackage.EJAVA_ANALYSIS_SCOPE__EXCLUSION_FILE_NAME: + setExclusionFileName((String)newValue); + return; + } + super.eSet(featureID, newValue); + } + + /** + * + * + * @generated + */ + public void eUnset(int featureID) { + switch (featureID) { + case JavaScopePackage.EJAVA_ANALYSIS_SCOPE__LOADERS: + getLoaders().clear(); + return; + case JavaScopePackage.EJAVA_ANALYSIS_SCOPE__EXCLUSION_FILE_NAME: + setExclusionFileName(EXCLUSION_FILE_NAME_EDEFAULT); + return; + } + super.eUnset(featureID); + } + + /** + * + * + * @generated + */ + public boolean eIsSet(int featureID) { + switch (featureID) { + case JavaScopePackage.EJAVA_ANALYSIS_SCOPE__LOADERS: + return loaders != null && !loaders.isEmpty(); + case JavaScopePackage.EJAVA_ANALYSIS_SCOPE__EXCLUSION_FILE_NAME: + return EXCLUSION_FILE_NAME_EDEFAULT == null ? exclusionFileName != null : !EXCLUSION_FILE_NAME_EDEFAULT.equals(exclusionFileName); + } + return super.eIsSet(featureID); + } + + /** + * + * + * @generated + */ + public String toString() { + if (eIsProxy()) return super.toString(); + + StringBuffer result = new StringBuffer(super.toString()); + result.append(" (exclusionFileName: "); + result.append(exclusionFileName); + result.append(')'); + return result.toString(); + } + +} //EJavaAnalysisScopeImpl \ No newline at end of file diff --git a/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/impl/ESourceFileImpl.java b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/impl/ESourceFileImpl.java new file mode 100644 index 000000000..395f4b601 --- /dev/null +++ b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/impl/ESourceFileImpl.java @@ -0,0 +1,42 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java.scope.impl; + +import org.eclipse.emf.ecore.EClass; + +import com.ibm.wala.ecore.java.scope.ESourceFile; +import com.ibm.wala.ecore.java.scope.JavaScopePackage; + +/** + * + * An implementation of the model object 'ESource File'. + * + *

                              + *

                              + * + * @generated + */ +public class ESourceFileImpl extends EFileImpl implements ESourceFile { + /** + * + * + * @generated + */ + protected ESourceFileImpl() { + super(); + } + + /** + * + * + * @generated + */ + protected EClass eStaticClass() { + return JavaScopePackage.Literals.ESOURCE_FILE; + } + +} //ESourceFileImpl \ No newline at end of file diff --git a/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/impl/JavaScopeFactoryImpl.java b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/impl/JavaScopeFactoryImpl.java new file mode 100644 index 000000000..b0252f27d --- /dev/null +++ b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/impl/JavaScopeFactoryImpl.java @@ -0,0 +1,247 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java.scope.impl; + +import com.ibm.wala.ecore.java.scope.*; + +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EDataType; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EPackage; + +import org.eclipse.emf.ecore.impl.EFactoryImpl; + +import org.eclipse.emf.ecore.plugin.EcorePlugin; + +/** + * + * An implementation of the model Factory. + * + * @generated + */ +public class JavaScopeFactoryImpl extends EFactoryImpl implements JavaScopeFactory { + /** + * Creates the default factory implementation. + * + * + * @generated + */ + public static JavaScopeFactory init() { + try { + JavaScopeFactory theJavaScopeFactory = (JavaScopeFactory)EPackage.Registry.INSTANCE.getEFactory("http:///com/ibm/wala/wala.ecore.java.scope"); + if (theJavaScopeFactory != null) { + return theJavaScopeFactory; + } + } + catch (Exception exception) { + EcorePlugin.INSTANCE.log(exception); + } + return new JavaScopeFactoryImpl(); + } + + /** + * Creates an instance of the factory. + * + * + * @generated + */ + public JavaScopeFactoryImpl() { + super(); + } + + /** + * + * + * @generated + */ + public EObject create(EClass eClass) { + switch (eClass.getClassifierID()) { + case JavaScopePackage.EJAVA_ANALYSIS_SCOPE: return createEJavaAnalysisScope(); + case JavaScopePackage.ECLASS_LOADER: return createEClassLoader(); + case JavaScopePackage.EBUILT_IN_MODULE: return createEBuiltInModule(); + case JavaScopePackage.EJAR_FILE: return createEJarFile(); + case JavaScopePackage.EFILE: return createEFile(); + case JavaScopePackage.ECLASS_FILE: return createEClassFile(); + case JavaScopePackage.ESOURCE_FILE: return createESourceFile(); + case JavaScopePackage.ECLASSPATH: return createEClasspath(); + default: + throw new IllegalArgumentException("The class '" + eClass.getName() + "' is not a valid classifier"); + } + } + + /** + * + * + * @generated + */ + public Object createFromString(EDataType eDataType, String initialValue) { + switch (eDataType.getClassifierID()) { + case JavaScopePackage.EBUILT_IN_RESOURCE: + return createEBuiltInResourceFromString(eDataType, initialValue); + case JavaScopePackage.ESTANDARD_CLASS_LOADER: + return createEStandardClassLoaderFromString(eDataType, initialValue); + default: + throw new IllegalArgumentException("The datatype '" + eDataType.getName() + "' is not a valid classifier"); + } + } + + /** + * + * + * @generated + */ + public String convertToString(EDataType eDataType, Object instanceValue) { + switch (eDataType.getClassifierID()) { + case JavaScopePackage.EBUILT_IN_RESOURCE: + return convertEBuiltInResourceToString(eDataType, instanceValue); + case JavaScopePackage.ESTANDARD_CLASS_LOADER: + return convertEStandardClassLoaderToString(eDataType, instanceValue); + default: + throw new IllegalArgumentException("The datatype '" + eDataType.getName() + "' is not a valid classifier"); + } + } + + /** + * + * + * @generated + */ + public EJavaAnalysisScope createEJavaAnalysisScope() { + EJavaAnalysisScopeImpl eJavaAnalysisScope = new EJavaAnalysisScopeImpl(); + return eJavaAnalysisScope; + } + + /** + * + * + * @generated + */ + public EClassLoader createEClassLoader() { + EClassLoaderImpl eClassLoader = new EClassLoaderImpl(); + return eClassLoader; + } + + /** + * + * + * @generated + */ + public EBuiltInModule createEBuiltInModule() { + EBuiltInModuleImpl eBuiltInModule = new EBuiltInModuleImpl(); + return eBuiltInModule; + } + + /** + * + * + * @generated + */ + public EJarFile createEJarFile() { + EJarFileImpl eJarFile = new EJarFileImpl(); + return eJarFile; + } + + /** + * + * + * @generated + */ + public EFile createEFile() { + EFileImpl eFile = new EFileImpl(); + return eFile; + } + + /** + * + * + * @generated + */ + public EClassFile createEClassFile() { + EClassFileImpl eClassFile = new EClassFileImpl(); + return eClassFile; + } + + /** + * + * + * @generated + */ + public ESourceFile createESourceFile() { + ESourceFileImpl eSourceFile = new ESourceFileImpl(); + return eSourceFile; + } + + /** + * + * + * @generated + */ + public EClasspath createEClasspath() { + EClasspathImpl eClasspath = new EClasspathImpl(); + return eClasspath; + } + + /** + * + * + * @generated + */ + public EBuiltInResource createEBuiltInResourceFromString(EDataType eDataType, String initialValue) { + EBuiltInResource result = EBuiltInResource.get(initialValue); + if (result == null) throw new IllegalArgumentException("The value '" + initialValue + "' is not a valid enumerator of '" + eDataType.getName() + "'"); + return result; + } + + /** + * + * + * @generated + */ + public String convertEBuiltInResourceToString(EDataType eDataType, Object instanceValue) { + return instanceValue == null ? null : instanceValue.toString(); + } + + /** + * + * + * @generated + */ + public EStandardClassLoader createEStandardClassLoaderFromString(EDataType eDataType, String initialValue) { + EStandardClassLoader result = EStandardClassLoader.get(initialValue); + if (result == null) throw new IllegalArgumentException("The value '" + initialValue + "' is not a valid enumerator of '" + eDataType.getName() + "'"); + return result; + } + + /** + * + * + * @generated + */ + public String convertEStandardClassLoaderToString(EDataType eDataType, Object instanceValue) { + return instanceValue == null ? null : instanceValue.toString(); + } + + /** + * + * + * @generated + */ + public JavaScopePackage getJavaScopePackage() { + return (JavaScopePackage)getEPackage(); + } + + /** + * + * + * @deprecated + * @generated + */ + public static JavaScopePackage getPackage() { + return JavaScopePackage.eINSTANCE; + } + +} //JavaScopeFactoryImpl diff --git a/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/impl/JavaScopePackageImpl.java b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/impl/JavaScopePackageImpl.java new file mode 100644 index 000000000..189a95f52 --- /dev/null +++ b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/impl/JavaScopePackageImpl.java @@ -0,0 +1,542 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java.scope.impl; + +import com.ibm.wala.ecore.common.CommonPackage; + +import com.ibm.wala.ecore.common.impl.CommonPackageImpl; + +import com.ibm.wala.ecore.graph.GraphPackage; + +import com.ibm.wala.ecore.graph.impl.GraphPackageImpl; + +import com.ibm.wala.ecore.j2ee.scope.J2EEScopePackage; + +import com.ibm.wala.ecore.j2ee.scope.impl.J2EEScopePackageImpl; + +import com.ibm.wala.ecore.java.JavaPackage; + +import com.ibm.wala.ecore.java.callGraph.CallGraphPackage; + +import com.ibm.wala.ecore.java.callGraph.impl.CallGraphPackageImpl; + +import com.ibm.wala.ecore.java.impl.JavaPackageImpl; + +import com.ibm.wala.ecore.java.pointerAnalysis.PointerAnalysisPackage; + +import com.ibm.wala.ecore.java.pointerAnalysis.impl.PointerAnalysisPackageImpl; + +import com.ibm.wala.ecore.java.scope.EBuiltInModule; +import com.ibm.wala.ecore.java.scope.EBuiltInResource; +import com.ibm.wala.ecore.java.scope.EClassFile; +import com.ibm.wala.ecore.java.scope.EClassLoader; +import com.ibm.wala.ecore.java.scope.EClasspath; +import com.ibm.wala.ecore.java.scope.EFile; +import com.ibm.wala.ecore.java.scope.EJarFile; +import com.ibm.wala.ecore.java.scope.EJavaAnalysisScope; +import com.ibm.wala.ecore.java.scope.EModule; +import com.ibm.wala.ecore.java.scope.ESourceFile; +import com.ibm.wala.ecore.java.scope.EStandardClassLoader; +import com.ibm.wala.ecore.java.scope.JavaScopeFactory; +import com.ibm.wala.ecore.java.scope.JavaScopePackage; + +import com.ibm.wala.ecore.perf.PerfPackage; + +import com.ibm.wala.ecore.perf.impl.PerfPackageImpl; + +import com.ibm.wala.ecore.regex.RegexPackage; + +import com.ibm.wala.ecore.regex.impl.RegexPackageImpl; + +import org.eclipse.emf.ecore.EAttribute; +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EEnum; +import org.eclipse.emf.ecore.EPackage; +import org.eclipse.emf.ecore.EReference; + +import org.eclipse.emf.ecore.impl.EPackageImpl; + +/** + * + * An implementation of the model Package. + * + * @generated + */ +public class JavaScopePackageImpl extends EPackageImpl implements JavaScopePackage { + /** + * + * + * @generated + */ + private EClass eJavaAnalysisScopeEClass = null; + + /** + * + * + * @generated + */ + private EClass eClassLoaderEClass = null; + + /** + * + * + * @generated + */ + private EClass eModuleEClass = null; + + /** + * + * + * @generated + */ + private EClass eBuiltInModuleEClass = null; + + /** + * + * + * @generated + */ + private EClass eJarFileEClass = null; + + /** + * + * + * @generated + */ + private EClass eFileEClass = null; + + /** + * + * + * @generated + */ + private EClass eClassFileEClass = null; + + /** + * + * + * @generated + */ + private EClass eSourceFileEClass = null; + + /** + * + * + * @generated + */ + private EClass eClasspathEClass = null; + + /** + * + * + * @generated + */ + private EEnum eBuiltInResourceEEnum = null; + + /** + * + * + * @generated + */ + private EEnum eStandardClassLoaderEEnum = null; + + /** + * Creates an instance of the model Package, registered with + * {@link org.eclipse.emf.ecore.EPackage.Registry EPackage.Registry} by the package + * package URI value. + *

                              Note: the correct way to create the package is via the static + * factory method {@link #init init()}, which also performs + * initialization of the package, or returns the registered package, + * if one already exists. + * + * + * @see org.eclipse.emf.ecore.EPackage.Registry + * @see com.ibm.wala.ecore.java.scope.JavaScopePackage#eNS_URI + * @see #init() + * @generated + */ + private JavaScopePackageImpl() { + super(eNS_URI, JavaScopeFactory.eINSTANCE); + } + + /** + * + * + * @generated + */ + private static boolean isInited = false; + + /** + * Creates, registers, and initializes the Package for this + * model, and for any others upon which it depends. Simple + * dependencies are satisfied by calling this method on all + * dependent packages before doing anything else. This method drives + * initialization for interdependent packages directly, in parallel + * with this package, itself. + *

                              Of this package and its interdependencies, all packages which + * have not yet been registered by their URI values are first created + * and registered. The packages are then initialized in two steps: + * meta-model objects for all of the packages are created before any + * are initialized, since one package's meta-model objects may refer to + * those of another. + *

                              Invocation of this method will not affect any packages that have + * already been initialized. + * + * + * @see #eNS_URI + * @see #createPackageContents() + * @see #initializePackageContents() + * @generated + */ + public static JavaScopePackage init() { + if (isInited) return (JavaScopePackage)EPackage.Registry.INSTANCE.getEPackage(JavaScopePackage.eNS_URI); + + // Obtain or create and register package + JavaScopePackageImpl theJavaScopePackage = (JavaScopePackageImpl)(EPackage.Registry.INSTANCE.getEPackage(eNS_URI) instanceof JavaScopePackageImpl ? EPackage.Registry.INSTANCE.getEPackage(eNS_URI) : new JavaScopePackageImpl()); + + isInited = true; + + // Obtain or create and register interdependencies + GraphPackageImpl theGraphPackage = (GraphPackageImpl)(EPackage.Registry.INSTANCE.getEPackage(GraphPackage.eNS_URI) instanceof GraphPackageImpl ? EPackage.Registry.INSTANCE.getEPackage(GraphPackage.eNS_URI) : GraphPackage.eINSTANCE); + CommonPackageImpl theCommonPackage = (CommonPackageImpl)(EPackage.Registry.INSTANCE.getEPackage(CommonPackage.eNS_URI) instanceof CommonPackageImpl ? EPackage.Registry.INSTANCE.getEPackage(CommonPackage.eNS_URI) : CommonPackage.eINSTANCE); + RegexPackageImpl theRegexPackage = (RegexPackageImpl)(EPackage.Registry.INSTANCE.getEPackage(RegexPackage.eNS_URI) instanceof RegexPackageImpl ? EPackage.Registry.INSTANCE.getEPackage(RegexPackage.eNS_URI) : RegexPackage.eINSTANCE); + PerfPackageImpl thePerfPackage = (PerfPackageImpl)(EPackage.Registry.INSTANCE.getEPackage(PerfPackage.eNS_URI) instanceof PerfPackageImpl ? EPackage.Registry.INSTANCE.getEPackage(PerfPackage.eNS_URI) : PerfPackage.eINSTANCE); + JavaPackageImpl theJavaPackage = (JavaPackageImpl)(EPackage.Registry.INSTANCE.getEPackage(JavaPackage.eNS_URI) instanceof JavaPackageImpl ? EPackage.Registry.INSTANCE.getEPackage(JavaPackage.eNS_URI) : JavaPackage.eINSTANCE); + CallGraphPackageImpl theCallGraphPackage = (CallGraphPackageImpl)(EPackage.Registry.INSTANCE.getEPackage(CallGraphPackage.eNS_URI) instanceof CallGraphPackageImpl ? EPackage.Registry.INSTANCE.getEPackage(CallGraphPackage.eNS_URI) : CallGraphPackage.eINSTANCE); + PointerAnalysisPackageImpl thePointerAnalysisPackage = (PointerAnalysisPackageImpl)(EPackage.Registry.INSTANCE.getEPackage(PointerAnalysisPackage.eNS_URI) instanceof PointerAnalysisPackageImpl ? EPackage.Registry.INSTANCE.getEPackage(PointerAnalysisPackage.eNS_URI) : PointerAnalysisPackage.eINSTANCE); + J2EEScopePackageImpl theJ2EEScopePackage = (J2EEScopePackageImpl)(EPackage.Registry.INSTANCE.getEPackage(J2EEScopePackage.eNS_URI) instanceof J2EEScopePackageImpl ? EPackage.Registry.INSTANCE.getEPackage(J2EEScopePackage.eNS_URI) : J2EEScopePackage.eINSTANCE); + + // Create package meta-data objects + theJavaScopePackage.createPackageContents(); + theGraphPackage.createPackageContents(); + theCommonPackage.createPackageContents(); + theRegexPackage.createPackageContents(); + thePerfPackage.createPackageContents(); + theJavaPackage.createPackageContents(); + theCallGraphPackage.createPackageContents(); + thePointerAnalysisPackage.createPackageContents(); + theJ2EEScopePackage.createPackageContents(); + + // Initialize created meta-data + theJavaScopePackage.initializePackageContents(); + theGraphPackage.initializePackageContents(); + theCommonPackage.initializePackageContents(); + theRegexPackage.initializePackageContents(); + thePerfPackage.initializePackageContents(); + theJavaPackage.initializePackageContents(); + theCallGraphPackage.initializePackageContents(); + thePointerAnalysisPackage.initializePackageContents(); + theJ2EEScopePackage.initializePackageContents(); + + // Mark meta-data to indicate it can't be changed + theJavaScopePackage.freeze(); + + return theJavaScopePackage; + } + + /** + * + * + * @generated + */ + public EClass getEJavaAnalysisScope() { + return eJavaAnalysisScopeEClass; + } + + /** + * + * + * @generated + */ + public EReference getEJavaAnalysisScope_Loaders() { + return (EReference)eJavaAnalysisScopeEClass.getEStructuralFeatures().get(0); + } + + /** + * + * + * @generated + */ + public EAttribute getEJavaAnalysisScope_ExclusionFileName() { + return (EAttribute)eJavaAnalysisScopeEClass.getEStructuralFeatures().get(1); + } + + /** + * + * + * @generated + */ + public EClass getEClassLoader() { + return eClassLoaderEClass; + } + + /** + * + * + * @generated + */ + public EReference getEClassLoader_Modules() { + return (EReference)eClassLoaderEClass.getEStructuralFeatures().get(0); + } + + /** + * + * + * @generated + */ + public EAttribute getEClassLoader_LoaderName() { + return (EAttribute)eClassLoaderEClass.getEStructuralFeatures().get(1); + } + + /** + * + * + * @generated + */ + public EClass getEModule() { + return eModuleEClass; + } + + /** + * + * + * @generated + */ + public EClass getEBuiltInModule() { + return eBuiltInModuleEClass; + } + + /** + * + * + * @generated + */ + public EAttribute getEBuiltInModule_Id() { + return (EAttribute)eBuiltInModuleEClass.getEStructuralFeatures().get(0); + } + + /** + * + * + * @generated + */ + public EClass getEJarFile() { + return eJarFileEClass; + } + + /** + * + * + * @generated + */ + public EAttribute getEJarFile_Url() { + return (EAttribute)eJarFileEClass.getEStructuralFeatures().get(0); + } + + /** + * + * + * @generated + */ + public EClass getEFile() { + return eFileEClass; + } + + /** + * + * + * @generated + */ + public EAttribute getEFile_Url() { + return (EAttribute)eFileEClass.getEStructuralFeatures().get(0); + } + + /** + * + * + * @generated + */ + public EClass getEClassFile() { + return eClassFileEClass; + } + + /** + * + * + * @generated + */ + public EClass getESourceFile() { + return eSourceFileEClass; + } + + /** + * + * + * @generated + */ + public EClass getEClasspath() { + return eClasspathEClass; + } + + /** + * + * + * @generated + */ + public EAttribute getEClasspath_String() { + return (EAttribute)eClasspathEClass.getEStructuralFeatures().get(0); + } + + /** + * + * + * @generated + */ + public EEnum getEBuiltInResource() { + return eBuiltInResourceEEnum; + } + + /** + * + * + * @generated + */ + public EEnum getEStandardClassLoader() { + return eStandardClassLoaderEEnum; + } + + /** + * + * + * @generated + */ + public JavaScopeFactory getJavaScopeFactory() { + return (JavaScopeFactory)getEFactoryInstance(); + } + + /** + * + * + * @generated + */ + private boolean isCreated = false; + + /** + * Creates the meta-model objects for the package. This method is + * guarded to have no affect on any invocation but its first. + * + * + * @generated + */ + public void createPackageContents() { + if (isCreated) return; + isCreated = true; + + // Create classes and their features + eJavaAnalysisScopeEClass = createEClass(EJAVA_ANALYSIS_SCOPE); + createEReference(eJavaAnalysisScopeEClass, EJAVA_ANALYSIS_SCOPE__LOADERS); + createEAttribute(eJavaAnalysisScopeEClass, EJAVA_ANALYSIS_SCOPE__EXCLUSION_FILE_NAME); + + eClassLoaderEClass = createEClass(ECLASS_LOADER); + createEReference(eClassLoaderEClass, ECLASS_LOADER__MODULES); + createEAttribute(eClassLoaderEClass, ECLASS_LOADER__LOADER_NAME); + + eModuleEClass = createEClass(EMODULE); + + eBuiltInModuleEClass = createEClass(EBUILT_IN_MODULE); + createEAttribute(eBuiltInModuleEClass, EBUILT_IN_MODULE__ID); + + eJarFileEClass = createEClass(EJAR_FILE); + createEAttribute(eJarFileEClass, EJAR_FILE__URL); + + eFileEClass = createEClass(EFILE); + createEAttribute(eFileEClass, EFILE__URL); + + eClassFileEClass = createEClass(ECLASS_FILE); + + eSourceFileEClass = createEClass(ESOURCE_FILE); + + eClasspathEClass = createEClass(ECLASSPATH); + createEAttribute(eClasspathEClass, ECLASSPATH__STRING); + + // Create enums + eBuiltInResourceEEnum = createEEnum(EBUILT_IN_RESOURCE); + eStandardClassLoaderEEnum = createEEnum(ESTANDARD_CLASS_LOADER); + } + + /** + * + * + * @generated + */ + private boolean isInitialized = false; + + /** + * Complete the initialization of the package and its meta-model. This + * method is guarded to have no affect on any invocation but its first. + * + * + * @generated + */ + public void initializePackageContents() { + if (isInitialized) return; + isInitialized = true; + + // Initialize package + setName(eNAME); + setNsPrefix(eNS_PREFIX); + setNsURI(eNS_URI); + + // Add supertypes to classes + eBuiltInModuleEClass.getESuperTypes().add(this.getEModule()); + eJarFileEClass.getESuperTypes().add(this.getEModule()); + eFileEClass.getESuperTypes().add(this.getEModule()); + eClassFileEClass.getESuperTypes().add(this.getEFile()); + eSourceFileEClass.getESuperTypes().add(this.getEFile()); + + // Initialize classes and features; add operations and parameters + initEClass(eJavaAnalysisScopeEClass, EJavaAnalysisScope.class, "EJavaAnalysisScope", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); + initEReference(getEJavaAnalysisScope_Loaders(), this.getEClassLoader(), null, "loaders", null, 1, -1, EJavaAnalysisScope.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, IS_COMPOSITE, !IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); + initEAttribute(getEJavaAnalysisScope_ExclusionFileName(), ecorePackage.getEString(), "exclusionFileName", null, 0, 1, EJavaAnalysisScope.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); + + initEClass(eClassLoaderEClass, EClassLoader.class, "EClassLoader", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); + initEReference(getEClassLoader_Modules(), this.getEModule(), null, "modules", null, 1, -1, EClassLoader.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, IS_COMPOSITE, !IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); + initEAttribute(getEClassLoader_LoaderName(), ecorePackage.getEString(), "loaderName", null, 0, 1, EClassLoader.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); + + initEClass(eModuleEClass, EModule.class, "EModule", IS_ABSTRACT, IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); + + initEClass(eBuiltInModuleEClass, EBuiltInModule.class, "EBuiltInModule", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); + initEAttribute(getEBuiltInModule_Id(), this.getEBuiltInResource(), "id", null, 1, 1, EBuiltInModule.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); + + initEClass(eJarFileEClass, EJarFile.class, "EJarFile", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); + initEAttribute(getEJarFile_Url(), ecorePackage.getEString(), "url", null, 1, 1, EJarFile.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); + + initEClass(eFileEClass, EFile.class, "EFile", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); + initEAttribute(getEFile_Url(), ecorePackage.getEString(), "url", null, 1, 1, EFile.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); + + initEClass(eClassFileEClass, EClassFile.class, "EClassFile", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); + + initEClass(eSourceFileEClass, ESourceFile.class, "ESourceFile", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); + + initEClass(eClasspathEClass, EClasspath.class, "EClasspath", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); + initEAttribute(getEClasspath_String(), ecorePackage.getEString(), "string", null, 1, 1, EClasspath.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); + + // Initialize enums and add enum literals + initEEnum(eBuiltInResourceEEnum, EBuiltInResource.class, "EBuiltInResource"); + addEEnumLiteral(eBuiltInResourceEEnum, EBuiltInResource.DEFAULT_J2SE_LIBS_LITERAL); + addEEnumLiteral(eBuiltInResourceEEnum, EBuiltInResource.DEFAULT_J2EE_LIBS_LITERAL); + addEEnumLiteral(eBuiltInResourceEEnum, EBuiltInResource.PRIMORDIAL_JAR_MODEL_LITERAL); + addEEnumLiteral(eBuiltInResourceEEnum, EBuiltInResource.EXTENSION_JAR_MODEL_LITERAL); + + initEEnum(eStandardClassLoaderEEnum, EStandardClassLoader.class, "EStandardClassLoader"); + addEEnumLiteral(eStandardClassLoaderEEnum, EStandardClassLoader.PRIMORDIAL_LITERAL); + addEEnumLiteral(eStandardClassLoaderEEnum, EStandardClassLoader.EXTENSION_LITERAL); + addEEnumLiteral(eStandardClassLoaderEEnum, EStandardClassLoader.APPLICATION_LITERAL); + addEEnumLiteral(eStandardClassLoaderEEnum, EStandardClassLoader.SYNTHETIC_LITERAL); + } + +} //JavaScopePackageImpl diff --git a/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/util/JavaScopeAdapterFactory.java b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/util/JavaScopeAdapterFactory.java new file mode 100644 index 000000000..fced91907 --- /dev/null +++ b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/util/JavaScopeAdapterFactory.java @@ -0,0 +1,256 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java.scope.util; + +import com.ibm.wala.ecore.java.scope.*; + +import org.eclipse.emf.common.notify.Adapter; +import org.eclipse.emf.common.notify.Notifier; + +import org.eclipse.emf.common.notify.impl.AdapterFactoryImpl; + +import org.eclipse.emf.ecore.EObject; + +/** + * + * The Adapter Factory for the model. + * It provides an adapter createXXX method for each class of the model. + * + * @see com.ibm.wala.ecore.java.scope.JavaScopePackage + * @generated + */ +public class JavaScopeAdapterFactory extends AdapterFactoryImpl { + /** + * The cached model package. + * + * + * @generated + */ + protected static JavaScopePackage modelPackage; + + /** + * Creates an instance of the adapter factory. + * + * + * @generated + */ + public JavaScopeAdapterFactory() { + if (modelPackage == null) { + modelPackage = JavaScopePackage.eINSTANCE; + } + } + + /** + * Returns whether this factory is applicable for the type of the object. + * + * This implementation returns true if the object is either the model's package or is an instance object of the model. + * + * @return whether this factory is applicable for the type of the object. + * @generated + */ + public boolean isFactoryForType(Object object) { + if (object == modelPackage) { + return true; + } + if (object instanceof EObject) { + return ((EObject)object).eClass().getEPackage() == modelPackage; + } + return false; + } + + /** + * The switch the delegates to the createXXX methods. + * + * + * @generated + */ + protected JavaScopeSwitch modelSwitch = + new JavaScopeSwitch() { + public Object caseEJavaAnalysisScope(EJavaAnalysisScope object) { + return createEJavaAnalysisScopeAdapter(); + } + public Object caseEClassLoader(EClassLoader object) { + return createEClassLoaderAdapter(); + } + public Object caseEModule(EModule object) { + return createEModuleAdapter(); + } + public Object caseEBuiltInModule(EBuiltInModule object) { + return createEBuiltInModuleAdapter(); + } + public Object caseEJarFile(EJarFile object) { + return createEJarFileAdapter(); + } + public Object caseEFile(EFile object) { + return createEFileAdapter(); + } + public Object caseEClassFile(EClassFile object) { + return createEClassFileAdapter(); + } + public Object caseESourceFile(ESourceFile object) { + return createESourceFileAdapter(); + } + public Object caseEClasspath(EClasspath object) { + return createEClasspathAdapter(); + } + public Object defaultCase(EObject object) { + return createEObjectAdapter(); + } + }; + + /** + * Creates an adapter for the target. + * + * + * @param target the object to adapt. + * @return the adapter for the target. + * @generated + */ + public Adapter createAdapter(Notifier target) { + return (Adapter)modelSwitch.doSwitch((EObject)target); + } + + + /** + * Creates a new adapter for an object of class '{@link com.ibm.wala.ecore.java.scope.EJavaAnalysisScope EJava Analysis Scope}'. + * + * This default implementation returns null so that we can easily ignore cases; + * it's useful to ignore a case when inheritance will catch all the cases anyway. + * + * @return the new adapter. + * @see com.ibm.wala.ecore.java.scope.EJavaAnalysisScope + * @generated + */ + public Adapter createEJavaAnalysisScopeAdapter() { + return null; + } + + /** + * Creates a new adapter for an object of class '{@link com.ibm.wala.ecore.java.scope.EClassLoader EClass Loader}'. + * + * This default implementation returns null so that we can easily ignore cases; + * it's useful to ignore a case when inheritance will catch all the cases anyway. + * + * @return the new adapter. + * @see com.ibm.wala.ecore.java.scope.EClassLoader + * @generated + */ + public Adapter createEClassLoaderAdapter() { + return null; + } + + /** + * Creates a new adapter for an object of class '{@link com.ibm.wala.ecore.java.scope.EModule EModule}'. + * + * This default implementation returns null so that we can easily ignore cases; + * it's useful to ignore a case when inheritance will catch all the cases anyway. + * + * @return the new adapter. + * @see com.ibm.wala.ecore.java.scope.EModule + * @generated + */ + public Adapter createEModuleAdapter() { + return null; + } + + /** + * Creates a new adapter for an object of class '{@link com.ibm.wala.ecore.java.scope.EBuiltInModule EBuilt In Module}'. + * + * This default implementation returns null so that we can easily ignore cases; + * it's useful to ignore a case when inheritance will catch all the cases anyway. + * + * @return the new adapter. + * @see com.ibm.wala.ecore.java.scope.EBuiltInModule + * @generated + */ + public Adapter createEBuiltInModuleAdapter() { + return null; + } + + /** + * Creates a new adapter for an object of class '{@link com.ibm.wala.ecore.java.scope.EJarFile EJar File}'. + * + * This default implementation returns null so that we can easily ignore cases; + * it's useful to ignore a case when inheritance will catch all the cases anyway. + * + * @return the new adapter. + * @see com.ibm.wala.ecore.java.scope.EJarFile + * @generated + */ + public Adapter createEJarFileAdapter() { + return null; + } + + /** + * Creates a new adapter for an object of class '{@link com.ibm.wala.ecore.java.scope.EFile EFile}'. + * + * This default implementation returns null so that we can easily ignore cases; + * it's useful to ignore a case when inheritance will catch all the cases anyway. + * + * @return the new adapter. + * @see com.ibm.wala.ecore.java.scope.EFile + * @generated + */ + public Adapter createEFileAdapter() { + return null; + } + + /** + * Creates a new adapter for an object of class '{@link com.ibm.wala.ecore.java.scope.EClassFile EClass File}'. + * + * This default implementation returns null so that we can easily ignore cases; + * it's useful to ignore a case when inheritance will catch all the cases anyway. + * + * @return the new adapter. + * @see com.ibm.wala.ecore.java.scope.EClassFile + * @generated + */ + public Adapter createEClassFileAdapter() { + return null; + } + + /** + * Creates a new adapter for an object of class '{@link com.ibm.wala.ecore.java.scope.ESourceFile ESource File}'. + * + * This default implementation returns null so that we can easily ignore cases; + * it's useful to ignore a case when inheritance will catch all the cases anyway. + * + * @return the new adapter. + * @see com.ibm.wala.ecore.java.scope.ESourceFile + * @generated + */ + public Adapter createESourceFileAdapter() { + return null; + } + + /** + * Creates a new adapter for an object of class '{@link com.ibm.wala.ecore.java.scope.EClasspath EClasspath}'. + * + * This default implementation returns null so that we can easily ignore cases; + * it's useful to ignore a case when inheritance will catch all the cases anyway. + * + * @return the new adapter. + * @see com.ibm.wala.ecore.java.scope.EClasspath + * @generated + */ + public Adapter createEClasspathAdapter() { + return null; + } + + /** + * Creates a new adapter for the default case. + * + * This default implementation returns null. + * + * @return the new adapter. + * @generated + */ + public Adapter createEObjectAdapter() { + return null; + } + +} //JavaScopeAdapterFactory diff --git a/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/util/JavaScopeSwitch.java b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/util/JavaScopeSwitch.java new file mode 100644 index 000000000..77c43ed52 --- /dev/null +++ b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/util/JavaScopeSwitch.java @@ -0,0 +1,305 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java.scope.util; + +import com.ibm.wala.ecore.java.scope.*; + +import java.util.List; + +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EObject; + +/** + * + * The Switch for the model's inheritance hierarchy. + * It supports the call {@link #doSwitch(EObject) doSwitch(object)} + * to invoke the caseXXX method for each class of the model, + * starting with the actual class of the object + * and proceeding up the inheritance hierarchy + * until a non-null result is returned, + * which is the result of the switch. + * + * @see com.ibm.wala.ecore.java.scope.JavaScopePackage + * @generated + */ +public class JavaScopeSwitch { + /** + * The cached model package + * + * + * @generated + */ + protected static JavaScopePackage modelPackage; + + /** + * Creates an instance of the switch. + * + * + * @generated + */ + public JavaScopeSwitch() { + if (modelPackage == null) { + modelPackage = JavaScopePackage.eINSTANCE; + } + } + + /** + * Calls caseXXX for each class of the model until one returns a non null result; it yields that result. + * + * + * @return the first non-null result returned by a caseXXX call. + * @generated + */ + public Object doSwitch(EObject theEObject) { + return doSwitch(theEObject.eClass(), theEObject); + } + + /** + * Calls caseXXX for each class of the model until one returns a non null result; it yields that result. + * + * + * @return the first non-null result returned by a caseXXX call. + * @generated + */ + protected Object doSwitch(EClass theEClass, EObject theEObject) { + if (theEClass.eContainer() == modelPackage) { + return doSwitch(theEClass.getClassifierID(), theEObject); + } + else { + List eSuperTypes = theEClass.getESuperTypes(); + return + eSuperTypes.isEmpty() ? + defaultCase(theEObject) : + doSwitch((EClass)eSuperTypes.get(0), theEObject); + } + } + + /** + * Calls caseXXX for each class of the model until one returns a non null result; it yields that result. + * + * + * @return the first non-null result returned by a caseXXX call. + * @generated + */ + protected Object doSwitch(int classifierID, EObject theEObject) { + switch (classifierID) { + case JavaScopePackage.EJAVA_ANALYSIS_SCOPE: { + EJavaAnalysisScope eJavaAnalysisScope = (EJavaAnalysisScope)theEObject; + Object result = caseEJavaAnalysisScope(eJavaAnalysisScope); + if (result == null) result = defaultCase(theEObject); + return result; + } + case JavaScopePackage.ECLASS_LOADER: { + EClassLoader eClassLoader = (EClassLoader)theEObject; + Object result = caseEClassLoader(eClassLoader); + if (result == null) result = defaultCase(theEObject); + return result; + } + case JavaScopePackage.EMODULE: { + EModule eModule = (EModule)theEObject; + Object result = caseEModule(eModule); + if (result == null) result = defaultCase(theEObject); + return result; + } + case JavaScopePackage.EBUILT_IN_MODULE: { + EBuiltInModule eBuiltInModule = (EBuiltInModule)theEObject; + Object result = caseEBuiltInModule(eBuiltInModule); + if (result == null) result = caseEModule(eBuiltInModule); + if (result == null) result = defaultCase(theEObject); + return result; + } + case JavaScopePackage.EJAR_FILE: { + EJarFile eJarFile = (EJarFile)theEObject; + Object result = caseEJarFile(eJarFile); + if (result == null) result = caseEModule(eJarFile); + if (result == null) result = defaultCase(theEObject); + return result; + } + case JavaScopePackage.EFILE: { + EFile eFile = (EFile)theEObject; + Object result = caseEFile(eFile); + if (result == null) result = caseEModule(eFile); + if (result == null) result = defaultCase(theEObject); + return result; + } + case JavaScopePackage.ECLASS_FILE: { + EClassFile eClassFile = (EClassFile)theEObject; + Object result = caseEClassFile(eClassFile); + if (result == null) result = caseEFile(eClassFile); + if (result == null) result = caseEModule(eClassFile); + if (result == null) result = defaultCase(theEObject); + return result; + } + case JavaScopePackage.ESOURCE_FILE: { + ESourceFile eSourceFile = (ESourceFile)theEObject; + Object result = caseESourceFile(eSourceFile); + if (result == null) result = caseEFile(eSourceFile); + if (result == null) result = caseEModule(eSourceFile); + if (result == null) result = defaultCase(theEObject); + return result; + } + case JavaScopePackage.ECLASSPATH: { + EClasspath eClasspath = (EClasspath)theEObject; + Object result = caseEClasspath(eClasspath); + if (result == null) result = defaultCase(theEObject); + return result; + } + default: return defaultCase(theEObject); + } + } + + /** + * Returns the result of interpretting the object as an instance of 'EJava Analysis Scope'. + * + * This implementation returns null; + * returning a non-null result will terminate the switch. + * + * @param object the target of the switch. + * @return the result of interpretting the object as an instance of 'EJava Analysis Scope'. + * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject) + * @generated + */ + public Object caseEJavaAnalysisScope(EJavaAnalysisScope object) { + return null; + } + + /** + * Returns the result of interpretting the object as an instance of 'EClass Loader'. + * + * This implementation returns null; + * returning a non-null result will terminate the switch. + * + * @param object the target of the switch. + * @return the result of interpretting the object as an instance of 'EClass Loader'. + * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject) + * @generated + */ + public Object caseEClassLoader(EClassLoader object) { + return null; + } + + /** + * Returns the result of interpretting the object as an instance of 'EModule'. + * + * This implementation returns null; + * returning a non-null result will terminate the switch. + * + * @param object the target of the switch. + * @return the result of interpretting the object as an instance of 'EModule'. + * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject) + * @generated + */ + public Object caseEModule(EModule object) { + return null; + } + + /** + * Returns the result of interpretting the object as an instance of 'EBuilt In Module'. + * + * This implementation returns null; + * returning a non-null result will terminate the switch. + * + * @param object the target of the switch. + * @return the result of interpretting the object as an instance of 'EBuilt In Module'. + * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject) + * @generated + */ + public Object caseEBuiltInModule(EBuiltInModule object) { + return null; + } + + /** + * Returns the result of interpretting the object as an instance of 'EJar File'. + * + * This implementation returns null; + * returning a non-null result will terminate the switch. + * + * @param object the target of the switch. + * @return the result of interpretting the object as an instance of 'EJar File'. + * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject) + * @generated + */ + public Object caseEJarFile(EJarFile object) { + return null; + } + + /** + * Returns the result of interpretting the object as an instance of 'EFile'. + * + * This implementation returns null; + * returning a non-null result will terminate the switch. + * + * @param object the target of the switch. + * @return the result of interpretting the object as an instance of 'EFile'. + * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject) + * @generated + */ + public Object caseEFile(EFile object) { + return null; + } + + /** + * Returns the result of interpretting the object as an instance of 'EClass File'. + * + * This implementation returns null; + * returning a non-null result will terminate the switch. + * + * @param object the target of the switch. + * @return the result of interpretting the object as an instance of 'EClass File'. + * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject) + * @generated + */ + public Object caseEClassFile(EClassFile object) { + return null; + } + + /** + * Returns the result of interpretting the object as an instance of 'ESource File'. + * + * This implementation returns null; + * returning a non-null result will terminate the switch. + * + * @param object the target of the switch. + * @return the result of interpretting the object as an instance of 'ESource File'. + * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject) + * @generated + */ + public Object caseESourceFile(ESourceFile object) { + return null; + } + + /** + * Returns the result of interpretting the object as an instance of 'EClasspath'. + * + * This implementation returns null; + * returning a non-null result will terminate the switch. + * + * @param object the target of the switch. + * @return the result of interpretting the object as an instance of 'EClasspath'. + * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject) + * @generated + */ + public Object caseEClasspath(EClasspath object) { + return null; + } + + /** + * Returns the result of interpretting the object as an instance of 'EObject'. + * + * This implementation returns null; + * returning a non-null result will terminate the switch, but this is the last case anyway. + * + * @param object the target of the switch. + * @return the result of interpretting the object as an instance of 'EObject'. + * @see #doSwitch(org.eclipse.emf.ecore.EObject) + * @generated + */ + public Object defaultCase(EObject object) { + return null; + } + +} //JavaScopeSwitch diff --git a/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/util/JavaAdapterFactory.java b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/util/JavaAdapterFactory.java new file mode 100644 index 000000000..b81541f3d --- /dev/null +++ b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/util/JavaAdapterFactory.java @@ -0,0 +1,261 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java.util; + +import com.ibm.wala.ecore.common.EObjectWithContainerId; + +import com.ibm.wala.ecore.graph.EGraph; +import com.ibm.wala.ecore.graph.ETree; + +import com.ibm.wala.ecore.java.*; + +import org.eclipse.emf.common.notify.Adapter; +import org.eclipse.emf.common.notify.Notifier; + +import org.eclipse.emf.common.notify.impl.AdapterFactoryImpl; + +import org.eclipse.emf.ecore.EObject; + +/** + * + * The Adapter Factory for the model. + * It provides an adapter createXXX method for each class of the model. + * + * @see com.ibm.wala.ecore.java.JavaPackage + * @generated + */ +public class JavaAdapterFactory extends AdapterFactoryImpl { + /** + * The cached model package. + * + * + * @generated + */ + protected static JavaPackage modelPackage; + + /** + * Creates an instance of the adapter factory. + * + * + * @generated + */ + public JavaAdapterFactory() { + if (modelPackage == null) { + modelPackage = JavaPackage.eINSTANCE; + } + } + + /** + * Returns whether this factory is applicable for the type of the object. + * + * This implementation returns true if the object is either the model's package or is an instance object of the model. + * + * @return whether this factory is applicable for the type of the object. + * @generated + */ + public boolean isFactoryForType(Object object) { + if (object == modelPackage) { + return true; + } + if (object instanceof EObject) { + return ((EObject)object).eClass().getEPackage() == modelPackage; + } + return false; + } + + /** + * The switch the delegates to the createXXX methods. + * + * + * @generated + */ + protected JavaSwitch modelSwitch = + new JavaSwitch() { + public Object caseEJavaClass(EJavaClass object) { + return createEJavaClassAdapter(); + } + public Object caseEJavaMethod(EJavaMethod object) { + return createEJavaMethodAdapter(); + } + public Object caseECallSite(ECallSite object) { + return createECallSiteAdapter(); + } + public Object caseEClassHierarchy(EClassHierarchy object) { + return createEClassHierarchyAdapter(); + } + public Object caseEInterfaceHierarchy(EInterfaceHierarchy object) { + return createEInterfaceHierarchyAdapter(); + } + public Object caseETypeHierarchy(ETypeHierarchy object) { + return createETypeHierarchyAdapter(); + } + public Object caseEObjectWithContainerId(EObjectWithContainerId object) { + return createEObjectWithContainerIdAdapter(); + } + public Object caseEGraph(EGraph object) { + return createEGraphAdapter(); + } + public Object caseETree(ETree object) { + return createETreeAdapter(); + } + public Object defaultCase(EObject object) { + return createEObjectAdapter(); + } + }; + + /** + * Creates an adapter for the target. + * + * + * @param target the object to adapt. + * @return the adapter for the target. + * @generated + */ + public Adapter createAdapter(Notifier target) { + return (Adapter)modelSwitch.doSwitch((EObject)target); + } + + + /** + * Creates a new adapter for an object of class '{@link com.ibm.wala.ecore.java.EJavaClass EJava Class}'. + * + * This default implementation returns null so that we can easily ignore cases; + * it's useful to ignore a case when inheritance will catch all the cases anyway. + * + * @return the new adapter. + * @see com.ibm.wala.ecore.java.EJavaClass + * @generated + */ + public Adapter createEJavaClassAdapter() { + return null; + } + + /** + * Creates a new adapter for an object of class '{@link com.ibm.wala.ecore.java.EJavaMethod EJava Method}'. + * + * This default implementation returns null so that we can easily ignore cases; + * it's useful to ignore a case when inheritance will catch all the cases anyway. + * + * @return the new adapter. + * @see com.ibm.wala.ecore.java.EJavaMethod + * @generated + */ + public Adapter createEJavaMethodAdapter() { + return null; + } + + /** + * Creates a new adapter for an object of class '{@link com.ibm.wala.ecore.java.ECallSite ECall Site}'. + * + * This default implementation returns null so that we can easily ignore cases; + * it's useful to ignore a case when inheritance will catch all the cases anyway. + * + * @return the new adapter. + * @see com.ibm.wala.ecore.java.ECallSite + * @generated + */ + public Adapter createECallSiteAdapter() { + return null; + } + + /** + * Creates a new adapter for an object of class '{@link com.ibm.wala.ecore.java.EClassHierarchy EClass Hierarchy}'. + * + * This default implementation returns null so that we can easily ignore cases; + * it's useful to ignore a case when inheritance will catch all the cases anyway. + * + * @return the new adapter. + * @see com.ibm.wala.ecore.java.EClassHierarchy + * @generated + */ + public Adapter createEClassHierarchyAdapter() { + return null; + } + + /** + * Creates a new adapter for an object of class '{@link com.ibm.wala.ecore.java.EInterfaceHierarchy EInterface Hierarchy}'. + * + * This default implementation returns null so that we can easily ignore cases; + * it's useful to ignore a case when inheritance will catch all the cases anyway. + * + * @return the new adapter. + * @see com.ibm.wala.ecore.java.EInterfaceHierarchy + * @generated + */ + public Adapter createEInterfaceHierarchyAdapter() { + return null; + } + + /** + * Creates a new adapter for an object of class '{@link com.ibm.wala.ecore.java.ETypeHierarchy EType Hierarchy}'. + * + * This default implementation returns null so that we can easily ignore cases; + * it's useful to ignore a case when inheritance will catch all the cases anyway. + * + * @return the new adapter. + * @see com.ibm.wala.ecore.java.ETypeHierarchy + * @generated + */ + public Adapter createETypeHierarchyAdapter() { + return null; + } + + /** + * Creates a new adapter for an object of class '{@link com.ibm.wala.ecore.common.EObjectWithContainerId EObject With Container Id}'. + * + * This default implementation returns null so that we can easily ignore cases; + * it's useful to ignore a case when inheritance will catch all the cases anyway. + * + * @return the new adapter. + * @see com.ibm.wala.ecore.common.EObjectWithContainerId + * @generated + */ + public Adapter createEObjectWithContainerIdAdapter() { + return null; + } + + /** + * Creates a new adapter for an object of class '{@link com.ibm.wala.ecore.graph.EGraph EGraph}'. + * + * This default implementation returns null so that we can easily ignore cases; + * it's useful to ignore a case when inheritance will catch all the cases anyway. + * + * @return the new adapter. + * @see com.ibm.wala.ecore.graph.EGraph + * @generated + */ + public Adapter createEGraphAdapter() { + return null; + } + + /** + * Creates a new adapter for an object of class '{@link com.ibm.wala.ecore.graph.ETree ETree}'. + * + * This default implementation returns null so that we can easily ignore cases; + * it's useful to ignore a case when inheritance will catch all the cases anyway. + * + * @return the new adapter. + * @see com.ibm.wala.ecore.graph.ETree + * @generated + */ + public Adapter createETreeAdapter() { + return null; + } + + /** + * Creates a new adapter for the default case. + * + * This default implementation returns null. + * + * @return the new adapter. + * @generated + */ + public Adapter createEObjectAdapter() { + return null; + } + +} //JavaAdapterFactory diff --git a/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/util/JavaSwitch.java b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/util/JavaSwitch.java new file mode 100644 index 000000000..2b49b4729 --- /dev/null +++ b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/util/JavaSwitch.java @@ -0,0 +1,291 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java.util; + +import com.ibm.wala.ecore.common.EObjectWithContainerId; + +import com.ibm.wala.ecore.graph.EGraph; +import com.ibm.wala.ecore.graph.ETree; + +import com.ibm.wala.ecore.java.*; + +import java.util.List; + +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EObject; + +/** + * + * The Switch for the model's inheritance hierarchy. + * It supports the call {@link #doSwitch(EObject) doSwitch(object)} + * to invoke the caseXXX method for each class of the model, + * starting with the actual class of the object + * and proceeding up the inheritance hierarchy + * until a non-null result is returned, + * which is the result of the switch. + * + * @see com.ibm.wala.ecore.java.JavaPackage + * @generated + */ +public class JavaSwitch { + /** + * The cached model package + * + * + * @generated + */ + protected static JavaPackage modelPackage; + + /** + * Creates an instance of the switch. + * + * + * @generated + */ + public JavaSwitch() { + if (modelPackage == null) { + modelPackage = JavaPackage.eINSTANCE; + } + } + + /** + * Calls caseXXX for each class of the model until one returns a non null result; it yields that result. + * + * + * @return the first non-null result returned by a caseXXX call. + * @generated + */ + public Object doSwitch(EObject theEObject) { + return doSwitch(theEObject.eClass(), theEObject); + } + + /** + * Calls caseXXX for each class of the model until one returns a non null result; it yields that result. + * + * + * @return the first non-null result returned by a caseXXX call. + * @generated + */ + protected Object doSwitch(EClass theEClass, EObject theEObject) { + if (theEClass.eContainer() == modelPackage) { + return doSwitch(theEClass.getClassifierID(), theEObject); + } + else { + List eSuperTypes = theEClass.getESuperTypes(); + return + eSuperTypes.isEmpty() ? + defaultCase(theEObject) : + doSwitch((EClass)eSuperTypes.get(0), theEObject); + } + } + + /** + * Calls caseXXX for each class of the model until one returns a non null result; it yields that result. + * + * + * @return the first non-null result returned by a caseXXX call. + * @generated + */ + protected Object doSwitch(int classifierID, EObject theEObject) { + switch (classifierID) { + case JavaPackage.EJAVA_CLASS: { + EJavaClass eJavaClass = (EJavaClass)theEObject; + Object result = caseEJavaClass(eJavaClass); + if (result == null) result = caseEObjectWithContainerId(eJavaClass); + if (result == null) result = defaultCase(theEObject); + return result; + } + case JavaPackage.EJAVA_METHOD: { + EJavaMethod eJavaMethod = (EJavaMethod)theEObject; + Object result = caseEJavaMethod(eJavaMethod); + if (result == null) result = caseEObjectWithContainerId(eJavaMethod); + if (result == null) result = defaultCase(theEObject); + return result; + } + case JavaPackage.ECALL_SITE: { + ECallSite eCallSite = (ECallSite)theEObject; + Object result = caseECallSite(eCallSite); + if (result == null) result = caseEObjectWithContainerId(eCallSite); + if (result == null) result = defaultCase(theEObject); + return result; + } + case JavaPackage.ECLASS_HIERARCHY: { + EClassHierarchy eClassHierarchy = (EClassHierarchy)theEObject; + Object result = caseEClassHierarchy(eClassHierarchy); + if (result == null) result = caseETree(eClassHierarchy); + if (result == null) result = caseEGraph(eClassHierarchy); + if (result == null) result = defaultCase(theEObject); + return result; + } + case JavaPackage.EINTERFACE_HIERARCHY: { + EInterfaceHierarchy eInterfaceHierarchy = (EInterfaceHierarchy)theEObject; + Object result = caseEInterfaceHierarchy(eInterfaceHierarchy); + if (result == null) result = caseEGraph(eInterfaceHierarchy); + if (result == null) result = defaultCase(theEObject); + return result; + } + case JavaPackage.ETYPE_HIERARCHY: { + ETypeHierarchy eTypeHierarchy = (ETypeHierarchy)theEObject; + Object result = caseETypeHierarchy(eTypeHierarchy); + if (result == null) result = defaultCase(theEObject); + return result; + } + default: return defaultCase(theEObject); + } + } + + /** + * Returns the result of interpretting the object as an instance of 'EJava Class'. + * + * This implementation returns null; + * returning a non-null result will terminate the switch. + * + * @param object the target of the switch. + * @return the result of interpretting the object as an instance of 'EJava Class'. + * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject) + * @generated + */ + public Object caseEJavaClass(EJavaClass object) { + return null; + } + + /** + * Returns the result of interpretting the object as an instance of 'EJava Method'. + * + * This implementation returns null; + * returning a non-null result will terminate the switch. + * + * @param object the target of the switch. + * @return the result of interpretting the object as an instance of 'EJava Method'. + * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject) + * @generated + */ + public Object caseEJavaMethod(EJavaMethod object) { + return null; + } + + /** + * Returns the result of interpretting the object as an instance of 'ECall Site'. + * + * This implementation returns null; + * returning a non-null result will terminate the switch. + * + * @param object the target of the switch. + * @return the result of interpretting the object as an instance of 'ECall Site'. + * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject) + * @generated + */ + public Object caseECallSite(ECallSite object) { + return null; + } + + /** + * Returns the result of interpretting the object as an instance of 'EClass Hierarchy'. + * + * This implementation returns null; + * returning a non-null result will terminate the switch. + * + * @param object the target of the switch. + * @return the result of interpretting the object as an instance of 'EClass Hierarchy'. + * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject) + * @generated + */ + public Object caseEClassHierarchy(EClassHierarchy object) { + return null; + } + + /** + * Returns the result of interpretting the object as an instance of 'EInterface Hierarchy'. + * + * This implementation returns null; + * returning a non-null result will terminate the switch. + * + * @param object the target of the switch. + * @return the result of interpretting the object as an instance of 'EInterface Hierarchy'. + * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject) + * @generated + */ + public Object caseEInterfaceHierarchy(EInterfaceHierarchy object) { + return null; + } + + /** + * Returns the result of interpretting the object as an instance of 'EType Hierarchy'. + * + * This implementation returns null; + * returning a non-null result will terminate the switch. + * + * @param object the target of the switch. + * @return the result of interpretting the object as an instance of 'EType Hierarchy'. + * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject) + * @generated + */ + public Object caseETypeHierarchy(ETypeHierarchy object) { + return null; + } + + /** + * Returns the result of interpretting the object as an instance of 'EObject With Container Id'. + * + * This implementation returns null; + * returning a non-null result will terminate the switch. + * + * @param object the target of the switch. + * @return the result of interpretting the object as an instance of 'EObject With Container Id'. + * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject) + * @generated + */ + public Object caseEObjectWithContainerId(EObjectWithContainerId object) { + return null; + } + + /** + * Returns the result of interpretting the object as an instance of 'EGraph'. + * + * This implementation returns null; + * returning a non-null result will terminate the switch. + * + * @param object the target of the switch. + * @return the result of interpretting the object as an instance of 'EGraph'. + * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject) + * @generated + */ + public Object caseEGraph(EGraph object) { + return null; + } + + /** + * Returns the result of interpretting the object as an instance of 'ETree'. + * + * This implementation returns null; + * returning a non-null result will terminate the switch. + * + * @param object the target of the switch. + * @return the result of interpretting the object as an instance of 'ETree'. + * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject) + * @generated + */ + public Object caseETree(ETree object) { + return null; + } + + /** + * Returns the result of interpretting the object as an instance of 'EObject'. + * + * This implementation returns null; + * returning a non-null result will terminate the switch, but this is the last case anyway. + * + * @param object the target of the switch. + * @return the result of interpretting the object as an instance of 'EObject'. + * @see #doSwitch(org.eclipse.emf.ecore.EObject) + * @generated + */ + public Object defaultCase(EObject object) { + return null; + } + +} //JavaSwitch diff --git a/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/perf/EPhaseTiming.java b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/perf/EPhaseTiming.java new file mode 100644 index 000000000..56ced45a4 --- /dev/null +++ b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/perf/EPhaseTiming.java @@ -0,0 +1,108 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.perf; + +import org.eclipse.emf.ecore.EObject; + +/** + * + * A representation of the model object 'EPhase Timing'. + * + * + *

                              + * The following features are supported: + *

                                + *
                              • {@link com.ibm.wala.ecore.perf.EPhaseTiming#getName Name}
                              • + *
                              • {@link com.ibm.wala.ecore.perf.EPhaseTiming#getMillis Millis}
                              • + *
                              • {@link com.ibm.wala.ecore.perf.EPhaseTiming#getOrder Order}
                              • + *
                              + *

                              + * + * @see com.ibm.wala.ecore.perf.PerfPackage#getEPhaseTiming() + * @model + * @generated + */ +public interface EPhaseTiming extends EObject { + /** + * Returns the value of the 'Name' attribute. + * + *

                              + * If the meaning of the 'Name' attribute isn't clear, + * there really should be more of a description here... + *

                              + * + * @return the value of the 'Name' attribute. + * @see #setName(String) + * @see com.ibm.wala.ecore.perf.PerfPackage#getEPhaseTiming_Name() + * @model required="true" + * @generated + */ + String getName(); + + /** + * Sets the value of the '{@link com.ibm.wala.ecore.perf.EPhaseTiming#getName Name}' attribute. + * + * + * @param value the new value of the 'Name' attribute. + * @see #getName() + * @generated + */ + void setName(String value); + + /** + * Returns the value of the 'Millis' attribute. + * + *

                              + * If the meaning of the 'Millis' attribute isn't clear, + * there really should be more of a description here... + *

                              + * + * @return the value of the 'Millis' attribute. + * @see #setMillis(long) + * @see com.ibm.wala.ecore.perf.PerfPackage#getEPhaseTiming_Millis() + * @model required="true" + * @generated + */ + long getMillis(); + + /** + * Sets the value of the '{@link com.ibm.wala.ecore.perf.EPhaseTiming#getMillis Millis}' attribute. + * + * + * @param value the new value of the 'Millis' attribute. + * @see #getMillis() + * @generated + */ + void setMillis(long value); + + /** + * Returns the value of the 'Order' attribute. + * + *

                              + * If the meaning of the 'Order' attribute isn't clear, + * there really should be more of a description here... + *

                              + * + * @return the value of the 'Order' attribute. + * @see #setOrder(int) + * @see com.ibm.wala.ecore.perf.PerfPackage#getEPhaseTiming_Order() + * @model required="true" + * @generated + */ + int getOrder(); + + /** + * Sets the value of the '{@link com.ibm.wala.ecore.perf.EPhaseTiming#getOrder Order}' attribute. + * + * + * @param value the new value of the 'Order' attribute. + * @see #getOrder() + * @generated + */ + void setOrder(int value); + +} // EPhaseTiming \ No newline at end of file diff --git a/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/perf/PerfFactory.java b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/perf/PerfFactory.java new file mode 100644 index 000000000..ae0109ef6 --- /dev/null +++ b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/perf/PerfFactory.java @@ -0,0 +1,46 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.perf; + +import org.eclipse.emf.ecore.EFactory; + +/** + * + * The Factory for the model. + * It provides a create method for each non-abstract class of the model. + * + * @see com.ibm.wala.ecore.perf.PerfPackage + * @generated + */ +public interface PerfFactory extends EFactory { + /** + * The singleton instance of the factory. + * + * + * @generated + */ + PerfFactory eINSTANCE = com.ibm.wala.ecore.perf.impl.PerfFactoryImpl.init(); + + /** + * Returns a new object of class 'EPhase Timing'. + * + * + * @return a new object of class 'EPhase Timing'. + * @generated + */ + EPhaseTiming createEPhaseTiming(); + + /** + * Returns the package supported by this factory. + * + * + * @return the package supported by this factory. + * @generated + */ + PerfPackage getPerfPackage(); + +} //PerfFactory diff --git a/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/perf/PerfPackage.java b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/perf/PerfPackage.java new file mode 100644 index 000000000..9fa95ddb0 --- /dev/null +++ b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/perf/PerfPackage.java @@ -0,0 +1,209 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.perf; + +import org.eclipse.emf.ecore.EAttribute; +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EPackage; + +/** + * + * The Package for the model. + * It contains accessors for the meta objects to represent + *
                                + *
                              • each class,
                              • + *
                              • each feature of each class,
                              • + *
                              • each enum,
                              • + *
                              • and each data type
                              • + *
                              + * + * @see com.ibm.wala.ecore.perf.PerfFactory + * @model kind="package" + * @generated + */ +public interface PerfPackage extends EPackage { + /** + * The package name. + * + * + * @generated + */ + String eNAME = "perf"; + + /** + * The package namespace URI. + * + * + * @generated + */ + String eNS_URI = "http:///com/ibm/wala/wala.ecore.perf"; + + /** + * The package namespace name. + * + * + * @generated + */ + String eNS_PREFIX = "com.ibm.wala.perf"; + + /** + * The singleton instance of the package. + * + * + * @generated + */ + PerfPackage eINSTANCE = com.ibm.wala.ecore.perf.impl.PerfPackageImpl.init(); + + /** + * The meta object id for the '{@link com.ibm.wala.ecore.perf.impl.EPhaseTimingImpl EPhase Timing}' class. + * + * + * @see com.ibm.wala.ecore.perf.impl.EPhaseTimingImpl + * @see com.ibm.wala.ecore.perf.impl.PerfPackageImpl#getEPhaseTiming() + * @generated + */ + int EPHASE_TIMING = 0; + + /** + * The feature id for the 'Name' attribute. + * + * + * @generated + * @ordered + */ + int EPHASE_TIMING__NAME = 0; + + /** + * The feature id for the 'Millis' attribute. + * + * + * @generated + * @ordered + */ + int EPHASE_TIMING__MILLIS = 1; + + /** + * The feature id for the 'Order' attribute. + * + * + * @generated + * @ordered + */ + int EPHASE_TIMING__ORDER = 2; + + /** + * The number of structural features of the 'EPhase Timing' class. + * + * + * @generated + * @ordered + */ + int EPHASE_TIMING_FEATURE_COUNT = 3; + + + /** + * Returns the meta object for class '{@link com.ibm.wala.ecore.perf.EPhaseTiming EPhase Timing}'. + * + * + * @return the meta object for class 'EPhase Timing'. + * @see com.ibm.wala.ecore.perf.EPhaseTiming + * @generated + */ + EClass getEPhaseTiming(); + + /** + * Returns the meta object for the attribute '{@link com.ibm.wala.ecore.perf.EPhaseTiming#getName Name}'. + * + * + * @return the meta object for the attribute 'Name'. + * @see com.ibm.wala.ecore.perf.EPhaseTiming#getName() + * @see #getEPhaseTiming() + * @generated + */ + EAttribute getEPhaseTiming_Name(); + + /** + * Returns the meta object for the attribute '{@link com.ibm.wala.ecore.perf.EPhaseTiming#getMillis Millis}'. + * + * + * @return the meta object for the attribute 'Millis'. + * @see com.ibm.wala.ecore.perf.EPhaseTiming#getMillis() + * @see #getEPhaseTiming() + * @generated + */ + EAttribute getEPhaseTiming_Millis(); + + /** + * Returns the meta object for the attribute '{@link com.ibm.wala.ecore.perf.EPhaseTiming#getOrder Order}'. + * + * + * @return the meta object for the attribute 'Order'. + * @see com.ibm.wala.ecore.perf.EPhaseTiming#getOrder() + * @see #getEPhaseTiming() + * @generated + */ + EAttribute getEPhaseTiming_Order(); + + /** + * Returns the factory that creates the instances of the model. + * + * + * @return the factory that creates the instances of the model. + * @generated + */ + PerfFactory getPerfFactory(); + + /** + * + * Defines literals for the meta objects that represent + *
                                + *
                              • each class,
                              • + *
                              • each feature of each class,
                              • + *
                              • each enum,
                              • + *
                              • and each data type
                              • + *
                              + * + * @generated + */ + interface Literals { + /** + * The meta object literal for the '{@link com.ibm.wala.ecore.perf.impl.EPhaseTimingImpl EPhase Timing}' class. + * + * + * @see com.ibm.wala.ecore.perf.impl.EPhaseTimingImpl + * @see com.ibm.wala.ecore.perf.impl.PerfPackageImpl#getEPhaseTiming() + * @generated + */ + EClass EPHASE_TIMING = eINSTANCE.getEPhaseTiming(); + + /** + * The meta object literal for the 'Name' attribute feature. + * + * + * @generated + */ + EAttribute EPHASE_TIMING__NAME = eINSTANCE.getEPhaseTiming_Name(); + + /** + * The meta object literal for the 'Millis' attribute feature. + * + * + * @generated + */ + EAttribute EPHASE_TIMING__MILLIS = eINSTANCE.getEPhaseTiming_Millis(); + + /** + * The meta object literal for the 'Order' attribute feature. + * + * + * @generated + */ + EAttribute EPHASE_TIMING__ORDER = eINSTANCE.getEPhaseTiming_Order(); + + } + +} //PerfPackage diff --git a/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/perf/impl/EPhaseTimingImpl.java b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/perf/impl/EPhaseTimingImpl.java new file mode 100644 index 000000000..4ea219af6 --- /dev/null +++ b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/perf/impl/EPhaseTimingImpl.java @@ -0,0 +1,269 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.perf.impl; + +import com.ibm.wala.ecore.perf.EPhaseTiming; +import com.ibm.wala.ecore.perf.PerfPackage; + +import org.eclipse.emf.common.notify.Notification; + +import org.eclipse.emf.ecore.EClass; + +import org.eclipse.emf.ecore.impl.ENotificationImpl; +import org.eclipse.emf.ecore.impl.EObjectImpl; + +/** + * + * An implementation of the model object 'EPhase Timing'. + * + *

                              + * The following features are implemented: + *

                                + *
                              • {@link com.ibm.wala.ecore.perf.impl.EPhaseTimingImpl#getName Name}
                              • + *
                              • {@link com.ibm.wala.ecore.perf.impl.EPhaseTimingImpl#getMillis Millis}
                              • + *
                              • {@link com.ibm.wala.ecore.perf.impl.EPhaseTimingImpl#getOrder Order}
                              • + *
                              + *

                              + * + * @generated + */ +public class EPhaseTimingImpl extends EObjectImpl implements EPhaseTiming { + /** + * The default value of the '{@link #getName() Name}' attribute. + * + * + * @see #getName() + * @generated + * @ordered + */ + protected static final String NAME_EDEFAULT = null; + + /** + * The cached value of the '{@link #getName() Name}' attribute. + * + * + * @see #getName() + * @generated + * @ordered + */ + protected String name = NAME_EDEFAULT; + + /** + * The default value of the '{@link #getMillis() Millis}' attribute. + * + * + * @see #getMillis() + * @generated + * @ordered + */ + protected static final long MILLIS_EDEFAULT = 0L; + + /** + * The cached value of the '{@link #getMillis() Millis}' attribute. + * + * + * @see #getMillis() + * @generated + * @ordered + */ + protected long millis = MILLIS_EDEFAULT; + + /** + * The default value of the '{@link #getOrder() Order}' attribute. + * + * + * @see #getOrder() + * @generated + * @ordered + */ + protected static final int ORDER_EDEFAULT = 0; + + /** + * The cached value of the '{@link #getOrder() Order}' attribute. + * + * + * @see #getOrder() + * @generated + * @ordered + */ + protected int order = ORDER_EDEFAULT; + + /** + * + * + * @generated + */ + protected EPhaseTimingImpl() { + super(); + } + + /** + * + * + * @generated + */ + protected EClass eStaticClass() { + return PerfPackage.Literals.EPHASE_TIMING; + } + + /** + * + * + * @generated + */ + public String getName() { + return name; + } + + /** + * + * + * @generated + */ + public void setName(String newName) { + String oldName = name; + name = newName; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, PerfPackage.EPHASE_TIMING__NAME, oldName, name)); + } + + /** + * + * + * @generated + */ + public long getMillis() { + return millis; + } + + /** + * + * + * @generated + */ + public void setMillis(long newMillis) { + long oldMillis = millis; + millis = newMillis; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, PerfPackage.EPHASE_TIMING__MILLIS, oldMillis, millis)); + } + + /** + * + * + * @generated + */ + public int getOrder() { + return order; + } + + /** + * + * + * @generated + */ + public void setOrder(int newOrder) { + int oldOrder = order; + order = newOrder; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, PerfPackage.EPHASE_TIMING__ORDER, oldOrder, order)); + } + + /** + * + * + * @generated + */ + public Object eGet(int featureID, boolean resolve, boolean coreType) { + switch (featureID) { + case PerfPackage.EPHASE_TIMING__NAME: + return getName(); + case PerfPackage.EPHASE_TIMING__MILLIS: + return new Long(getMillis()); + case PerfPackage.EPHASE_TIMING__ORDER: + return new Integer(getOrder()); + } + return super.eGet(featureID, resolve, coreType); + } + + /** + * + * + * @generated + */ + public void eSet(int featureID, Object newValue) { + switch (featureID) { + case PerfPackage.EPHASE_TIMING__NAME: + setName((String)newValue); + return; + case PerfPackage.EPHASE_TIMING__MILLIS: + setMillis(((Long)newValue).longValue()); + return; + case PerfPackage.EPHASE_TIMING__ORDER: + setOrder(((Integer)newValue).intValue()); + return; + } + super.eSet(featureID, newValue); + } + + /** + * + * + * @generated + */ + public void eUnset(int featureID) { + switch (featureID) { + case PerfPackage.EPHASE_TIMING__NAME: + setName(NAME_EDEFAULT); + return; + case PerfPackage.EPHASE_TIMING__MILLIS: + setMillis(MILLIS_EDEFAULT); + return; + case PerfPackage.EPHASE_TIMING__ORDER: + setOrder(ORDER_EDEFAULT); + return; + } + super.eUnset(featureID); + } + + /** + * + * + * @generated + */ + public boolean eIsSet(int featureID) { + switch (featureID) { + case PerfPackage.EPHASE_TIMING__NAME: + return NAME_EDEFAULT == null ? name != null : !NAME_EDEFAULT.equals(name); + case PerfPackage.EPHASE_TIMING__MILLIS: + return millis != MILLIS_EDEFAULT; + case PerfPackage.EPHASE_TIMING__ORDER: + return order != ORDER_EDEFAULT; + } + return super.eIsSet(featureID); + } + + /** + * + * + * @generated + */ + public String toString() { + if (eIsProxy()) return super.toString(); + + StringBuffer result = new StringBuffer(super.toString()); + result.append(" (name: "); + result.append(name); + result.append(", millis: "); + result.append(millis); + result.append(", order: "); + result.append(order); + result.append(')'); + return result.toString(); + } + +} //EPhaseTimingImpl \ No newline at end of file diff --git a/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/perf/impl/PerfFactoryImpl.java b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/perf/impl/PerfFactoryImpl.java new file mode 100644 index 000000000..f2ab9f7dd --- /dev/null +++ b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/perf/impl/PerfFactoryImpl.java @@ -0,0 +1,97 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.perf.impl; + +import com.ibm.wala.ecore.perf.*; + +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EPackage; + +import org.eclipse.emf.ecore.impl.EFactoryImpl; + +import org.eclipse.emf.ecore.plugin.EcorePlugin; + +/** + * + * An implementation of the model Factory. + * + * @generated + */ +public class PerfFactoryImpl extends EFactoryImpl implements PerfFactory { + /** + * Creates the default factory implementation. + * + * + * @generated + */ + public static PerfFactory init() { + try { + PerfFactory thePerfFactory = (PerfFactory)EPackage.Registry.INSTANCE.getEFactory("http:///com/ibm/wala/wala.ecore.perf"); + if (thePerfFactory != null) { + return thePerfFactory; + } + } + catch (Exception exception) { + EcorePlugin.INSTANCE.log(exception); + } + return new PerfFactoryImpl(); + } + + /** + * Creates an instance of the factory. + * + * + * @generated + */ + public PerfFactoryImpl() { + super(); + } + + /** + * + * + * @generated + */ + public EObject create(EClass eClass) { + switch (eClass.getClassifierID()) { + case PerfPackage.EPHASE_TIMING: return createEPhaseTiming(); + default: + throw new IllegalArgumentException("The class '" + eClass.getName() + "' is not a valid classifier"); + } + } + + /** + * + * + * @generated + */ + public EPhaseTiming createEPhaseTiming() { + EPhaseTimingImpl ePhaseTiming = new EPhaseTimingImpl(); + return ePhaseTiming; + } + + /** + * + * + * @generated + */ + public PerfPackage getPerfPackage() { + return (PerfPackage)getEPackage(); + } + + /** + * + * + * @deprecated + * @generated + */ + public static PerfPackage getPackage() { + return PerfPackage.eINSTANCE; + } + +} //PerfFactoryImpl diff --git a/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/perf/impl/PerfPackageImpl.java b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/perf/impl/PerfPackageImpl.java new file mode 100644 index 000000000..df9913bd5 --- /dev/null +++ b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/perf/impl/PerfPackageImpl.java @@ -0,0 +1,264 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.perf.impl; + +import com.ibm.wala.ecore.common.CommonPackage; + +import com.ibm.wala.ecore.common.impl.CommonPackageImpl; + +import com.ibm.wala.ecore.graph.GraphPackage; + +import com.ibm.wala.ecore.graph.impl.GraphPackageImpl; + +import com.ibm.wala.ecore.j2ee.scope.J2EEScopePackage; + +import com.ibm.wala.ecore.j2ee.scope.impl.J2EEScopePackageImpl; + +import com.ibm.wala.ecore.java.JavaPackage; + +import com.ibm.wala.ecore.java.callGraph.CallGraphPackage; + +import com.ibm.wala.ecore.java.callGraph.impl.CallGraphPackageImpl; + +import com.ibm.wala.ecore.java.impl.JavaPackageImpl; + +import com.ibm.wala.ecore.java.pointerAnalysis.PointerAnalysisPackage; + +import com.ibm.wala.ecore.java.pointerAnalysis.impl.PointerAnalysisPackageImpl; + +import com.ibm.wala.ecore.java.scope.JavaScopePackage; + +import com.ibm.wala.ecore.java.scope.impl.JavaScopePackageImpl; + +import com.ibm.wala.ecore.perf.EPhaseTiming; +import com.ibm.wala.ecore.perf.PerfFactory; +import com.ibm.wala.ecore.perf.PerfPackage; + +import com.ibm.wala.ecore.regex.RegexPackage; + +import com.ibm.wala.ecore.regex.impl.RegexPackageImpl; + +import org.eclipse.emf.ecore.EAttribute; +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EPackage; + +import org.eclipse.emf.ecore.impl.EPackageImpl; + +/** + * + * An implementation of the model Package. + * + * @generated + */ +public class PerfPackageImpl extends EPackageImpl implements PerfPackage { + /** + * + * + * @generated + */ + private EClass ePhaseTimingEClass = null; + + /** + * Creates an instance of the model Package, registered with + * {@link org.eclipse.emf.ecore.EPackage.Registry EPackage.Registry} by the package + * package URI value. + *

                              Note: the correct way to create the package is via the static + * factory method {@link #init init()}, which also performs + * initialization of the package, or returns the registered package, + * if one already exists. + * + * + * @see org.eclipse.emf.ecore.EPackage.Registry + * @see com.ibm.wala.ecore.perf.PerfPackage#eNS_URI + * @see #init() + * @generated + */ + private PerfPackageImpl() { + super(eNS_URI, PerfFactory.eINSTANCE); + } + + /** + * + * + * @generated + */ + private static boolean isInited = false; + + /** + * Creates, registers, and initializes the Package for this + * model, and for any others upon which it depends. Simple + * dependencies are satisfied by calling this method on all + * dependent packages before doing anything else. This method drives + * initialization for interdependent packages directly, in parallel + * with this package, itself. + *

                              Of this package and its interdependencies, all packages which + * have not yet been registered by their URI values are first created + * and registered. The packages are then initialized in two steps: + * meta-model objects for all of the packages are created before any + * are initialized, since one package's meta-model objects may refer to + * those of another. + *

                              Invocation of this method will not affect any packages that have + * already been initialized. + * + * + * @see #eNS_URI + * @see #createPackageContents() + * @see #initializePackageContents() + * @generated + */ + public static PerfPackage init() { + if (isInited) return (PerfPackage)EPackage.Registry.INSTANCE.getEPackage(PerfPackage.eNS_URI); + + // Obtain or create and register package + PerfPackageImpl thePerfPackage = (PerfPackageImpl)(EPackage.Registry.INSTANCE.getEPackage(eNS_URI) instanceof PerfPackageImpl ? EPackage.Registry.INSTANCE.getEPackage(eNS_URI) : new PerfPackageImpl()); + + isInited = true; + + // Obtain or create and register interdependencies + GraphPackageImpl theGraphPackage = (GraphPackageImpl)(EPackage.Registry.INSTANCE.getEPackage(GraphPackage.eNS_URI) instanceof GraphPackageImpl ? EPackage.Registry.INSTANCE.getEPackage(GraphPackage.eNS_URI) : GraphPackage.eINSTANCE); + CommonPackageImpl theCommonPackage = (CommonPackageImpl)(EPackage.Registry.INSTANCE.getEPackage(CommonPackage.eNS_URI) instanceof CommonPackageImpl ? EPackage.Registry.INSTANCE.getEPackage(CommonPackage.eNS_URI) : CommonPackage.eINSTANCE); + RegexPackageImpl theRegexPackage = (RegexPackageImpl)(EPackage.Registry.INSTANCE.getEPackage(RegexPackage.eNS_URI) instanceof RegexPackageImpl ? EPackage.Registry.INSTANCE.getEPackage(RegexPackage.eNS_URI) : RegexPackage.eINSTANCE); + JavaPackageImpl theJavaPackage = (JavaPackageImpl)(EPackage.Registry.INSTANCE.getEPackage(JavaPackage.eNS_URI) instanceof JavaPackageImpl ? EPackage.Registry.INSTANCE.getEPackage(JavaPackage.eNS_URI) : JavaPackage.eINSTANCE); + CallGraphPackageImpl theCallGraphPackage = (CallGraphPackageImpl)(EPackage.Registry.INSTANCE.getEPackage(CallGraphPackage.eNS_URI) instanceof CallGraphPackageImpl ? EPackage.Registry.INSTANCE.getEPackage(CallGraphPackage.eNS_URI) : CallGraphPackage.eINSTANCE); + PointerAnalysisPackageImpl thePointerAnalysisPackage = (PointerAnalysisPackageImpl)(EPackage.Registry.INSTANCE.getEPackage(PointerAnalysisPackage.eNS_URI) instanceof PointerAnalysisPackageImpl ? EPackage.Registry.INSTANCE.getEPackage(PointerAnalysisPackage.eNS_URI) : PointerAnalysisPackage.eINSTANCE); + JavaScopePackageImpl theJavaScopePackage = (JavaScopePackageImpl)(EPackage.Registry.INSTANCE.getEPackage(JavaScopePackage.eNS_URI) instanceof JavaScopePackageImpl ? EPackage.Registry.INSTANCE.getEPackage(JavaScopePackage.eNS_URI) : JavaScopePackage.eINSTANCE); + J2EEScopePackageImpl theJ2EEScopePackage = (J2EEScopePackageImpl)(EPackage.Registry.INSTANCE.getEPackage(J2EEScopePackage.eNS_URI) instanceof J2EEScopePackageImpl ? EPackage.Registry.INSTANCE.getEPackage(J2EEScopePackage.eNS_URI) : J2EEScopePackage.eINSTANCE); + + // Create package meta-data objects + thePerfPackage.createPackageContents(); + theGraphPackage.createPackageContents(); + theCommonPackage.createPackageContents(); + theRegexPackage.createPackageContents(); + theJavaPackage.createPackageContents(); + theCallGraphPackage.createPackageContents(); + thePointerAnalysisPackage.createPackageContents(); + theJavaScopePackage.createPackageContents(); + theJ2EEScopePackage.createPackageContents(); + + // Initialize created meta-data + thePerfPackage.initializePackageContents(); + theGraphPackage.initializePackageContents(); + theCommonPackage.initializePackageContents(); + theRegexPackage.initializePackageContents(); + theJavaPackage.initializePackageContents(); + theCallGraphPackage.initializePackageContents(); + thePointerAnalysisPackage.initializePackageContents(); + theJavaScopePackage.initializePackageContents(); + theJ2EEScopePackage.initializePackageContents(); + + // Mark meta-data to indicate it can't be changed + thePerfPackage.freeze(); + + return thePerfPackage; + } + + /** + * + * + * @generated + */ + public EClass getEPhaseTiming() { + return ePhaseTimingEClass; + } + + /** + * + * + * @generated + */ + public EAttribute getEPhaseTiming_Name() { + return (EAttribute)ePhaseTimingEClass.getEStructuralFeatures().get(0); + } + + /** + * + * + * @generated + */ + public EAttribute getEPhaseTiming_Millis() { + return (EAttribute)ePhaseTimingEClass.getEStructuralFeatures().get(1); + } + + /** + * + * + * @generated + */ + public EAttribute getEPhaseTiming_Order() { + return (EAttribute)ePhaseTimingEClass.getEStructuralFeatures().get(2); + } + + /** + * + * + * @generated + */ + public PerfFactory getPerfFactory() { + return (PerfFactory)getEFactoryInstance(); + } + + /** + * + * + * @generated + */ + private boolean isCreated = false; + + /** + * Creates the meta-model objects for the package. This method is + * guarded to have no affect on any invocation but its first. + * + * + * @generated + */ + public void createPackageContents() { + if (isCreated) return; + isCreated = true; + + // Create classes and their features + ePhaseTimingEClass = createEClass(EPHASE_TIMING); + createEAttribute(ePhaseTimingEClass, EPHASE_TIMING__NAME); + createEAttribute(ePhaseTimingEClass, EPHASE_TIMING__MILLIS); + createEAttribute(ePhaseTimingEClass, EPHASE_TIMING__ORDER); + } + + /** + * + * + * @generated + */ + private boolean isInitialized = false; + + /** + * Complete the initialization of the package and its meta-model. This + * method is guarded to have no affect on any invocation but its first. + * + * + * @generated + */ + public void initializePackageContents() { + if (isInitialized) return; + isInitialized = true; + + // Initialize package + setName(eNAME); + setNsPrefix(eNS_PREFIX); + setNsURI(eNS_URI); + + // Add supertypes to classes + + // Initialize classes and features; add operations and parameters + initEClass(ePhaseTimingEClass, EPhaseTiming.class, "EPhaseTiming", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); + initEAttribute(getEPhaseTiming_Name(), ecorePackage.getEString(), "name", null, 1, 1, EPhaseTiming.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); + initEAttribute(getEPhaseTiming_Millis(), ecorePackage.getELong(), "millis", null, 1, 1, EPhaseTiming.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); + initEAttribute(getEPhaseTiming_Order(), ecorePackage.getEInt(), "order", null, 1, 1, EPhaseTiming.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); + + // Create resource + createResource(eNS_URI); + } + +} //PerfPackageImpl diff --git a/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/perf/util/PerfAdapterFactory.java b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/perf/util/PerfAdapterFactory.java new file mode 100644 index 000000000..b2f08d451 --- /dev/null +++ b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/perf/util/PerfAdapterFactory.java @@ -0,0 +1,120 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.perf.util; + +import com.ibm.wala.ecore.perf.*; + +import org.eclipse.emf.common.notify.Adapter; +import org.eclipse.emf.common.notify.Notifier; + +import org.eclipse.emf.common.notify.impl.AdapterFactoryImpl; + +import org.eclipse.emf.ecore.EObject; + +/** + * + * The Adapter Factory for the model. + * It provides an adapter createXXX method for each class of the model. + * + * @see com.ibm.wala.ecore.perf.PerfPackage + * @generated + */ +public class PerfAdapterFactory extends AdapterFactoryImpl { + /** + * The cached model package. + * + * + * @generated + */ + protected static PerfPackage modelPackage; + + /** + * Creates an instance of the adapter factory. + * + * + * @generated + */ + public PerfAdapterFactory() { + if (modelPackage == null) { + modelPackage = PerfPackage.eINSTANCE; + } + } + + /** + * Returns whether this factory is applicable for the type of the object. + * + * This implementation returns true if the object is either the model's package or is an instance object of the model. + * + * @return whether this factory is applicable for the type of the object. + * @generated + */ + public boolean isFactoryForType(Object object) { + if (object == modelPackage) { + return true; + } + if (object instanceof EObject) { + return ((EObject)object).eClass().getEPackage() == modelPackage; + } + return false; + } + + /** + * The switch the delegates to the createXXX methods. + * + * + * @generated + */ + protected PerfSwitch modelSwitch = + new PerfSwitch() { + public Object caseEPhaseTiming(EPhaseTiming object) { + return createEPhaseTimingAdapter(); + } + public Object defaultCase(EObject object) { + return createEObjectAdapter(); + } + }; + + /** + * Creates an adapter for the target. + * + * + * @param target the object to adapt. + * @return the adapter for the target. + * @generated + */ + public Adapter createAdapter(Notifier target) { + return (Adapter)modelSwitch.doSwitch((EObject)target); + } + + + /** + * Creates a new adapter for an object of class '{@link com.ibm.wala.ecore.perf.EPhaseTiming EPhase Timing}'. + * + * This default implementation returns null so that we can easily ignore cases; + * it's useful to ignore a case when inheritance will catch all the cases anyway. + * + * @return the new adapter. + * @see com.ibm.wala.ecore.perf.EPhaseTiming + * @generated + */ + public Adapter createEPhaseTimingAdapter() { + return null; + } + + /** + * Creates a new adapter for the default case. + * + * This default implementation returns null. + * + * @return the new adapter. + * @generated + */ + public Adapter createEObjectAdapter() { + return null; + } + +} //PerfAdapterFactory diff --git a/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/perf/util/PerfSwitch.java b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/perf/util/PerfSwitch.java new file mode 100644 index 000000000..54bc90f21 --- /dev/null +++ b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/perf/util/PerfSwitch.java @@ -0,0 +1,130 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.perf.util; + +import com.ibm.wala.ecore.perf.*; + +import java.util.List; + +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EObject; + +/** + * + * The Switch for the model's inheritance hierarchy. + * It supports the call {@link #doSwitch(EObject) doSwitch(object)} + * to invoke the caseXXX method for each class of the model, + * starting with the actual class of the object + * and proceeding up the inheritance hierarchy + * until a non-null result is returned, + * which is the result of the switch. + * + * @see com.ibm.wala.ecore.perf.PerfPackage + * @generated + */ +public class PerfSwitch { + /** + * The cached model package + * + * + * @generated + */ + protected static PerfPackage modelPackage; + + /** + * Creates an instance of the switch. + * + * + * @generated + */ + public PerfSwitch() { + if (modelPackage == null) { + modelPackage = PerfPackage.eINSTANCE; + } + } + + /** + * Calls caseXXX for each class of the model until one returns a non null result; it yields that result. + * + * + * @return the first non-null result returned by a caseXXX call. + * @generated + */ + public Object doSwitch(EObject theEObject) { + return doSwitch(theEObject.eClass(), theEObject); + } + + /** + * Calls caseXXX for each class of the model until one returns a non null result; it yields that result. + * + * + * @return the first non-null result returned by a caseXXX call. + * @generated + */ + protected Object doSwitch(EClass theEClass, EObject theEObject) { + if (theEClass.eContainer() == modelPackage) { + return doSwitch(theEClass.getClassifierID(), theEObject); + } + else { + List eSuperTypes = theEClass.getESuperTypes(); + return + eSuperTypes.isEmpty() ? + defaultCase(theEObject) : + doSwitch((EClass)eSuperTypes.get(0), theEObject); + } + } + + /** + * Calls caseXXX for each class of the model until one returns a non null result; it yields that result. + * + * + * @return the first non-null result returned by a caseXXX call. + * @generated + */ + protected Object doSwitch(int classifierID, EObject theEObject) { + switch (classifierID) { + case PerfPackage.EPHASE_TIMING: { + EPhaseTiming ePhaseTiming = (EPhaseTiming)theEObject; + Object result = caseEPhaseTiming(ePhaseTiming); + if (result == null) result = defaultCase(theEObject); + return result; + } + default: return defaultCase(theEObject); + } + } + + /** + * Returns the result of interpretting the object as an instance of 'EPhase Timing'. + * + * This implementation returns null; + * returning a non-null result will terminate the switch. + * + * @param object the target of the switch. + * @return the result of interpretting the object as an instance of 'EPhase Timing'. + * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject) + * @generated + */ + public Object caseEPhaseTiming(EPhaseTiming object) { + return null; + } + + /** + * Returns the result of interpretting the object as an instance of 'EObject'. + * + * This implementation returns null; + * returning a non-null result will terminate the switch, but this is the last case anyway. + * + * @param object the target of the switch. + * @return the result of interpretting the object as an instance of 'EObject'. + * @see #doSwitch(org.eclipse.emf.ecore.EObject) + * @generated + */ + public Object defaultCase(EObject object) { + return null; + } + +} //PerfSwitch diff --git a/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/regex/EPattern.java b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/regex/EPattern.java new file mode 100644 index 000000000..feb8e20dd --- /dev/null +++ b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/regex/EPattern.java @@ -0,0 +1,54 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.regex; + +import org.eclipse.emf.ecore.EObject; + +/** + * + * A representation of the model object 'EPattern'. + * + * + *

                              + * The following features are supported: + *

                                + *
                              • {@link com.ibm.wala.ecore.regex.EPattern#getPattern Pattern}
                              • + *
                              + *

                              + * + * @see com.ibm.wala.ecore.regex.RegexPackage#getEPattern() + * @model + * @generated + */ +public interface EPattern extends EObject { + /** + * Returns the value of the 'Pattern' attribute. + * + *

                              + * If the meaning of the 'Pattern' attribute isn't clear, + * there really should be more of a description here... + *

                              + * + * @return the value of the 'Pattern' attribute. + * @see #setPattern(String) + * @see com.ibm.wala.ecore.regex.RegexPackage#getEPattern_Pattern() + * @model required="true" + * @generated + */ + String getPattern(); + + /** + * Sets the value of the '{@link com.ibm.wala.ecore.regex.EPattern#getPattern Pattern}' attribute. + * + * + * @param value the new value of the 'Pattern' attribute. + * @see #getPattern() + * @generated + */ + void setPattern(String value); + +} // EPattern \ No newline at end of file diff --git a/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/regex/RegexFactory.java b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/regex/RegexFactory.java new file mode 100644 index 000000000..b71d81439 --- /dev/null +++ b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/regex/RegexFactory.java @@ -0,0 +1,46 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.regex; + +import org.eclipse.emf.ecore.EFactory; + +/** + * + * The Factory for the model. + * It provides a create method for each non-abstract class of the model. + * + * @see com.ibm.wala.ecore.regex.RegexPackage + * @generated + */ +public interface RegexFactory extends EFactory { + /** + * The singleton instance of the factory. + * + * + * @generated + */ + RegexFactory eINSTANCE = com.ibm.wala.ecore.regex.impl.RegexFactoryImpl.init(); + + /** + * Returns a new object of class 'EPattern'. + * + * + * @return a new object of class 'EPattern'. + * @generated + */ + EPattern createEPattern(); + + /** + * Returns the package supported by this factory. + * + * + * @return the package supported by this factory. + * @generated + */ + RegexPackage getRegexPackage(); + +} //RegexFactory diff --git a/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/regex/RegexPackage.java b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/regex/RegexPackage.java new file mode 100644 index 000000000..7e6d30272 --- /dev/null +++ b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/regex/RegexPackage.java @@ -0,0 +1,153 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.regex; + +import org.eclipse.emf.ecore.EAttribute; +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EPackage; + +/** + * + * The Package for the model. + * It contains accessors for the meta objects to represent + *
                                + *
                              • each class,
                              • + *
                              • each feature of each class,
                              • + *
                              • each enum,
                              • + *
                              • and each data type
                              • + *
                              + * + * @see com.ibm.wala.ecore.regex.RegexFactory + * @model kind="package" + * @generated + */ +public interface RegexPackage extends EPackage { + /** + * The package name. + * + * + * @generated + */ + String eNAME = "regex"; + + /** + * The package namespace URI. + * + * + * @generated + */ + String eNS_URI = "http:///com/ibm/wala/wala.ecore.regex"; + + /** + * The package namespace name. + * + * + * @generated + */ + String eNS_PREFIX = "com.ibm.wala.regex"; + + /** + * The singleton instance of the package. + * + * + * @generated + */ + RegexPackage eINSTANCE = com.ibm.wala.ecore.regex.impl.RegexPackageImpl.init(); + + /** + * The meta object id for the '{@link com.ibm.wala.ecore.regex.impl.EPatternImpl EPattern}' class. + * + * + * @see com.ibm.wala.ecore.regex.impl.EPatternImpl + * @see com.ibm.wala.ecore.regex.impl.RegexPackageImpl#getEPattern() + * @generated + */ + int EPATTERN = 0; + + /** + * The feature id for the 'Pattern' attribute. + * + * + * @generated + * @ordered + */ + int EPATTERN__PATTERN = 0; + + /** + * The number of structural features of the 'EPattern' class. + * + * + * @generated + * @ordered + */ + int EPATTERN_FEATURE_COUNT = 1; + + + /** + * Returns the meta object for class '{@link com.ibm.wala.ecore.regex.EPattern EPattern}'. + * + * + * @return the meta object for class 'EPattern'. + * @see com.ibm.wala.ecore.regex.EPattern + * @generated + */ + EClass getEPattern(); + + /** + * Returns the meta object for the attribute '{@link com.ibm.wala.ecore.regex.EPattern#getPattern Pattern}'. + * + * + * @return the meta object for the attribute 'Pattern'. + * @see com.ibm.wala.ecore.regex.EPattern#getPattern() + * @see #getEPattern() + * @generated + */ + EAttribute getEPattern_Pattern(); + + /** + * Returns the factory that creates the instances of the model. + * + * + * @return the factory that creates the instances of the model. + * @generated + */ + RegexFactory getRegexFactory(); + + /** + * + * Defines literals for the meta objects that represent + *
                                + *
                              • each class,
                              • + *
                              • each feature of each class,
                              • + *
                              • each enum,
                              • + *
                              • and each data type
                              • + *
                              + * + * @generated + */ + interface Literals { + /** + * The meta object literal for the '{@link com.ibm.wala.ecore.regex.impl.EPatternImpl EPattern}' class. + * + * + * @see com.ibm.wala.ecore.regex.impl.EPatternImpl + * @see com.ibm.wala.ecore.regex.impl.RegexPackageImpl#getEPattern() + * @generated + */ + EClass EPATTERN = eINSTANCE.getEPattern(); + + /** + * The meta object literal for the 'Pattern' attribute feature. + * + * + * @generated + */ + EAttribute EPATTERN__PATTERN = eINSTANCE.getEPattern_Pattern(); + + } + +} //RegexPackage diff --git a/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/regex/impl/EPatternImpl.java b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/regex/impl/EPatternImpl.java new file mode 100644 index 000000000..f351fd6ab --- /dev/null +++ b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/regex/impl/EPatternImpl.java @@ -0,0 +1,161 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.regex.impl; + +import com.ibm.wala.ecore.regex.EPattern; +import com.ibm.wala.ecore.regex.RegexPackage; + +import org.eclipse.emf.common.notify.Notification; + +import org.eclipse.emf.ecore.EClass; + +import org.eclipse.emf.ecore.impl.ENotificationImpl; +import org.eclipse.emf.ecore.impl.EObjectImpl; + +/** + * + * An implementation of the model object 'EPattern'. + * + *

                              + * The following features are implemented: + *

                                + *
                              • {@link com.ibm.wala.ecore.regex.impl.EPatternImpl#getPattern Pattern}
                              • + *
                              + *

                              + * + * @generated + */ +public class EPatternImpl extends EObjectImpl implements EPattern { + /** + * The default value of the '{@link #getPattern() Pattern}' attribute. + * + * + * @see #getPattern() + * @generated + * @ordered + */ + protected static final String PATTERN_EDEFAULT = null; + + /** + * The cached value of the '{@link #getPattern() Pattern}' attribute. + * + * + * @see #getPattern() + * @generated + * @ordered + */ + protected String pattern = PATTERN_EDEFAULT; + + /** + * + * + * @generated + */ + protected EPatternImpl() { + super(); + } + + /** + * + * + * @generated + */ + protected EClass eStaticClass() { + return RegexPackage.Literals.EPATTERN; + } + + /** + * + * + * @generated + */ + public String getPattern() { + return pattern; + } + + /** + * + * + * @generated + */ + public void setPattern(String newPattern) { + String oldPattern = pattern; + pattern = newPattern; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, RegexPackage.EPATTERN__PATTERN, oldPattern, pattern)); + } + + /** + * + * + * @generated + */ + public Object eGet(int featureID, boolean resolve, boolean coreType) { + switch (featureID) { + case RegexPackage.EPATTERN__PATTERN: + return getPattern(); + } + return super.eGet(featureID, resolve, coreType); + } + + /** + * + * + * @generated + */ + public void eSet(int featureID, Object newValue) { + switch (featureID) { + case RegexPackage.EPATTERN__PATTERN: + setPattern((String)newValue); + return; + } + super.eSet(featureID, newValue); + } + + /** + * + * + * @generated + */ + public void eUnset(int featureID) { + switch (featureID) { + case RegexPackage.EPATTERN__PATTERN: + setPattern(PATTERN_EDEFAULT); + return; + } + super.eUnset(featureID); + } + + /** + * + * + * @generated + */ + public boolean eIsSet(int featureID) { + switch (featureID) { + case RegexPackage.EPATTERN__PATTERN: + return PATTERN_EDEFAULT == null ? pattern != null : !PATTERN_EDEFAULT.equals(pattern); + } + return super.eIsSet(featureID); + } + + /** + * + * + * @generated + */ + public String toString() { + if (eIsProxy()) return super.toString(); + + StringBuffer result = new StringBuffer(super.toString()); + result.append(" (pattern: "); + result.append(pattern); + result.append(')'); + return result.toString(); + } + +} //EPatternImpl \ No newline at end of file diff --git a/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/regex/impl/RegexFactoryImpl.java b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/regex/impl/RegexFactoryImpl.java new file mode 100644 index 000000000..1293b556c --- /dev/null +++ b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/regex/impl/RegexFactoryImpl.java @@ -0,0 +1,97 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.regex.impl; + +import com.ibm.wala.ecore.regex.*; + +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EPackage; + +import org.eclipse.emf.ecore.impl.EFactoryImpl; + +import org.eclipse.emf.ecore.plugin.EcorePlugin; + +/** + * + * An implementation of the model Factory. + * + * @generated + */ +public class RegexFactoryImpl extends EFactoryImpl implements RegexFactory { + /** + * Creates the default factory implementation. + * + * + * @generated + */ + public static RegexFactory init() { + try { + RegexFactory theRegexFactory = (RegexFactory)EPackage.Registry.INSTANCE.getEFactory("http:///com/ibm/wala/wala.ecore.regex"); + if (theRegexFactory != null) { + return theRegexFactory; + } + } + catch (Exception exception) { + EcorePlugin.INSTANCE.log(exception); + } + return new RegexFactoryImpl(); + } + + /** + * Creates an instance of the factory. + * + * + * @generated + */ + public RegexFactoryImpl() { + super(); + } + + /** + * + * + * @generated + */ + public EObject create(EClass eClass) { + switch (eClass.getClassifierID()) { + case RegexPackage.EPATTERN: return createEPattern(); + default: + throw new IllegalArgumentException("The class '" + eClass.getName() + "' is not a valid classifier"); + } + } + + /** + * + * + * @generated + */ + public EPattern createEPattern() { + EPatternImpl ePattern = new EPatternImpl(); + return ePattern; + } + + /** + * + * + * @generated + */ + public RegexPackage getRegexPackage() { + return (RegexPackage)getEPackage(); + } + + /** + * + * + * @deprecated + * @generated + */ + public static RegexPackage getPackage() { + return RegexPackage.eINSTANCE; + } + +} //RegexFactoryImpl diff --git a/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/regex/impl/RegexPackageImpl.java b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/regex/impl/RegexPackageImpl.java new file mode 100644 index 000000000..4c0c8041c --- /dev/null +++ b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/regex/impl/RegexPackageImpl.java @@ -0,0 +1,242 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.regex.impl; + +import com.ibm.wala.ecore.common.CommonPackage; + +import com.ibm.wala.ecore.common.impl.CommonPackageImpl; + +import com.ibm.wala.ecore.graph.GraphPackage; + +import com.ibm.wala.ecore.graph.impl.GraphPackageImpl; + +import com.ibm.wala.ecore.j2ee.scope.J2EEScopePackage; + +import com.ibm.wala.ecore.j2ee.scope.impl.J2EEScopePackageImpl; + +import com.ibm.wala.ecore.java.JavaPackage; + +import com.ibm.wala.ecore.java.callGraph.CallGraphPackage; + +import com.ibm.wala.ecore.java.callGraph.impl.CallGraphPackageImpl; + +import com.ibm.wala.ecore.java.impl.JavaPackageImpl; + +import com.ibm.wala.ecore.java.pointerAnalysis.PointerAnalysisPackage; + +import com.ibm.wala.ecore.java.pointerAnalysis.impl.PointerAnalysisPackageImpl; + +import com.ibm.wala.ecore.java.scope.JavaScopePackage; + +import com.ibm.wala.ecore.java.scope.impl.JavaScopePackageImpl; + +import com.ibm.wala.ecore.perf.PerfPackage; + +import com.ibm.wala.ecore.perf.impl.PerfPackageImpl; + +import com.ibm.wala.ecore.regex.EPattern; +import com.ibm.wala.ecore.regex.RegexFactory; +import com.ibm.wala.ecore.regex.RegexPackage; + +import org.eclipse.emf.ecore.EAttribute; +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EPackage; + +import org.eclipse.emf.ecore.impl.EPackageImpl; + +/** + * + * An implementation of the model Package. + * + * @generated + */ +public class RegexPackageImpl extends EPackageImpl implements RegexPackage { + /** + * + * + * @generated + */ + private EClass ePatternEClass = null; + + /** + * Creates an instance of the model Package, registered with + * {@link org.eclipse.emf.ecore.EPackage.Registry EPackage.Registry} by the package + * package URI value. + *

                              Note: the correct way to create the package is via the static + * factory method {@link #init init()}, which also performs + * initialization of the package, or returns the registered package, + * if one already exists. + * + * + * @see org.eclipse.emf.ecore.EPackage.Registry + * @see com.ibm.wala.ecore.regex.RegexPackage#eNS_URI + * @see #init() + * @generated + */ + private RegexPackageImpl() { + super(eNS_URI, RegexFactory.eINSTANCE); + } + + /** + * + * + * @generated + */ + private static boolean isInited = false; + + /** + * Creates, registers, and initializes the Package for this + * model, and for any others upon which it depends. Simple + * dependencies are satisfied by calling this method on all + * dependent packages before doing anything else. This method drives + * initialization for interdependent packages directly, in parallel + * with this package, itself. + *

                              Of this package and its interdependencies, all packages which + * have not yet been registered by their URI values are first created + * and registered. The packages are then initialized in two steps: + * meta-model objects for all of the packages are created before any + * are initialized, since one package's meta-model objects may refer to + * those of another. + *

                              Invocation of this method will not affect any packages that have + * already been initialized. + * + * + * @see #eNS_URI + * @see #createPackageContents() + * @see #initializePackageContents() + * @generated + */ + public static RegexPackage init() { + if (isInited) return (RegexPackage)EPackage.Registry.INSTANCE.getEPackage(RegexPackage.eNS_URI); + + // Obtain or create and register package + RegexPackageImpl theRegexPackage = (RegexPackageImpl)(EPackage.Registry.INSTANCE.getEPackage(eNS_URI) instanceof RegexPackageImpl ? EPackage.Registry.INSTANCE.getEPackage(eNS_URI) : new RegexPackageImpl()); + + isInited = true; + + // Obtain or create and register interdependencies + GraphPackageImpl theGraphPackage = (GraphPackageImpl)(EPackage.Registry.INSTANCE.getEPackage(GraphPackage.eNS_URI) instanceof GraphPackageImpl ? EPackage.Registry.INSTANCE.getEPackage(GraphPackage.eNS_URI) : GraphPackage.eINSTANCE); + CommonPackageImpl theCommonPackage = (CommonPackageImpl)(EPackage.Registry.INSTANCE.getEPackage(CommonPackage.eNS_URI) instanceof CommonPackageImpl ? EPackage.Registry.INSTANCE.getEPackage(CommonPackage.eNS_URI) : CommonPackage.eINSTANCE); + PerfPackageImpl thePerfPackage = (PerfPackageImpl)(EPackage.Registry.INSTANCE.getEPackage(PerfPackage.eNS_URI) instanceof PerfPackageImpl ? EPackage.Registry.INSTANCE.getEPackage(PerfPackage.eNS_URI) : PerfPackage.eINSTANCE); + JavaPackageImpl theJavaPackage = (JavaPackageImpl)(EPackage.Registry.INSTANCE.getEPackage(JavaPackage.eNS_URI) instanceof JavaPackageImpl ? EPackage.Registry.INSTANCE.getEPackage(JavaPackage.eNS_URI) : JavaPackage.eINSTANCE); + CallGraphPackageImpl theCallGraphPackage = (CallGraphPackageImpl)(EPackage.Registry.INSTANCE.getEPackage(CallGraphPackage.eNS_URI) instanceof CallGraphPackageImpl ? EPackage.Registry.INSTANCE.getEPackage(CallGraphPackage.eNS_URI) : CallGraphPackage.eINSTANCE); + PointerAnalysisPackageImpl thePointerAnalysisPackage = (PointerAnalysisPackageImpl)(EPackage.Registry.INSTANCE.getEPackage(PointerAnalysisPackage.eNS_URI) instanceof PointerAnalysisPackageImpl ? EPackage.Registry.INSTANCE.getEPackage(PointerAnalysisPackage.eNS_URI) : PointerAnalysisPackage.eINSTANCE); + JavaScopePackageImpl theJavaScopePackage = (JavaScopePackageImpl)(EPackage.Registry.INSTANCE.getEPackage(JavaScopePackage.eNS_URI) instanceof JavaScopePackageImpl ? EPackage.Registry.INSTANCE.getEPackage(JavaScopePackage.eNS_URI) : JavaScopePackage.eINSTANCE); + J2EEScopePackageImpl theJ2EEScopePackage = (J2EEScopePackageImpl)(EPackage.Registry.INSTANCE.getEPackage(J2EEScopePackage.eNS_URI) instanceof J2EEScopePackageImpl ? EPackage.Registry.INSTANCE.getEPackage(J2EEScopePackage.eNS_URI) : J2EEScopePackage.eINSTANCE); + + // Create package meta-data objects + theRegexPackage.createPackageContents(); + theGraphPackage.createPackageContents(); + theCommonPackage.createPackageContents(); + thePerfPackage.createPackageContents(); + theJavaPackage.createPackageContents(); + theCallGraphPackage.createPackageContents(); + thePointerAnalysisPackage.createPackageContents(); + theJavaScopePackage.createPackageContents(); + theJ2EEScopePackage.createPackageContents(); + + // Initialize created meta-data + theRegexPackage.initializePackageContents(); + theGraphPackage.initializePackageContents(); + theCommonPackage.initializePackageContents(); + thePerfPackage.initializePackageContents(); + theJavaPackage.initializePackageContents(); + theCallGraphPackage.initializePackageContents(); + thePointerAnalysisPackage.initializePackageContents(); + theJavaScopePackage.initializePackageContents(); + theJ2EEScopePackage.initializePackageContents(); + + // Mark meta-data to indicate it can't be changed + theRegexPackage.freeze(); + + return theRegexPackage; + } + + /** + * + * + * @generated + */ + public EClass getEPattern() { + return ePatternEClass; + } + + /** + * + * + * @generated + */ + public EAttribute getEPattern_Pattern() { + return (EAttribute)ePatternEClass.getEStructuralFeatures().get(0); + } + + /** + * + * + * @generated + */ + public RegexFactory getRegexFactory() { + return (RegexFactory)getEFactoryInstance(); + } + + /** + * + * + * @generated + */ + private boolean isCreated = false; + + /** + * Creates the meta-model objects for the package. This method is + * guarded to have no affect on any invocation but its first. + * + * + * @generated + */ + public void createPackageContents() { + if (isCreated) return; + isCreated = true; + + // Create classes and their features + ePatternEClass = createEClass(EPATTERN); + createEAttribute(ePatternEClass, EPATTERN__PATTERN); + } + + /** + * + * + * @generated + */ + private boolean isInitialized = false; + + /** + * Complete the initialization of the package and its meta-model. This + * method is guarded to have no affect on any invocation but its first. + * + * + * @generated + */ + public void initializePackageContents() { + if (isInitialized) return; + isInitialized = true; + + // Initialize package + setName(eNAME); + setNsPrefix(eNS_PREFIX); + setNsURI(eNS_URI); + + // Add supertypes to classes + + // Initialize classes and features; add operations and parameters + initEClass(ePatternEClass, EPattern.class, "EPattern", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); + initEAttribute(getEPattern_Pattern(), ecorePackage.getEString(), "pattern", null, 1, 1, EPattern.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); + + // Create resource + createResource(eNS_URI); + } + +} //RegexPackageImpl diff --git a/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/regex/util/RegexAdapterFactory.java b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/regex/util/RegexAdapterFactory.java new file mode 100644 index 000000000..9613970b9 --- /dev/null +++ b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/regex/util/RegexAdapterFactory.java @@ -0,0 +1,120 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.regex.util; + +import com.ibm.wala.ecore.regex.*; + +import org.eclipse.emf.common.notify.Adapter; +import org.eclipse.emf.common.notify.Notifier; + +import org.eclipse.emf.common.notify.impl.AdapterFactoryImpl; + +import org.eclipse.emf.ecore.EObject; + +/** + * + * The Adapter Factory for the model. + * It provides an adapter createXXX method for each class of the model. + * + * @see com.ibm.wala.ecore.regex.RegexPackage + * @generated + */ +public class RegexAdapterFactory extends AdapterFactoryImpl { + /** + * The cached model package. + * + * + * @generated + */ + protected static RegexPackage modelPackage; + + /** + * Creates an instance of the adapter factory. + * + * + * @generated + */ + public RegexAdapterFactory() { + if (modelPackage == null) { + modelPackage = RegexPackage.eINSTANCE; + } + } + + /** + * Returns whether this factory is applicable for the type of the object. + * + * This implementation returns true if the object is either the model's package or is an instance object of the model. + * + * @return whether this factory is applicable for the type of the object. + * @generated + */ + public boolean isFactoryForType(Object object) { + if (object == modelPackage) { + return true; + } + if (object instanceof EObject) { + return ((EObject)object).eClass().getEPackage() == modelPackage; + } + return false; + } + + /** + * The switch the delegates to the createXXX methods. + * + * + * @generated + */ + protected RegexSwitch modelSwitch = + new RegexSwitch() { + public Object caseEPattern(EPattern object) { + return createEPatternAdapter(); + } + public Object defaultCase(EObject object) { + return createEObjectAdapter(); + } + }; + + /** + * Creates an adapter for the target. + * + * + * @param target the object to adapt. + * @return the adapter for the target. + * @generated + */ + public Adapter createAdapter(Notifier target) { + return (Adapter)modelSwitch.doSwitch((EObject)target); + } + + + /** + * Creates a new adapter for an object of class '{@link com.ibm.wala.ecore.regex.EPattern EPattern}'. + * + * This default implementation returns null so that we can easily ignore cases; + * it's useful to ignore a case when inheritance will catch all the cases anyway. + * + * @return the new adapter. + * @see com.ibm.wala.ecore.regex.EPattern + * @generated + */ + public Adapter createEPatternAdapter() { + return null; + } + + /** + * Creates a new adapter for the default case. + * + * This default implementation returns null. + * + * @return the new adapter. + * @generated + */ + public Adapter createEObjectAdapter() { + return null; + } + +} //RegexAdapterFactory diff --git a/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/regex/util/RegexSwitch.java b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/regex/util/RegexSwitch.java new file mode 100644 index 000000000..8b4c0184f --- /dev/null +++ b/com.ibm.wala.emf/com.ibm.wala.emf/src/com/ibm/wala/ecore/regex/util/RegexSwitch.java @@ -0,0 +1,130 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.regex.util; + +import com.ibm.wala.ecore.regex.*; + +import java.util.List; + +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EObject; + +/** + * + * The Switch for the model's inheritance hierarchy. + * It supports the call {@link #doSwitch(EObject) doSwitch(object)} + * to invoke the caseXXX method for each class of the model, + * starting with the actual class of the object + * and proceeding up the inheritance hierarchy + * until a non-null result is returned, + * which is the result of the switch. + * + * @see com.ibm.wala.ecore.regex.RegexPackage + * @generated + */ +public class RegexSwitch { + /** + * The cached model package + * + * + * @generated + */ + protected static RegexPackage modelPackage; + + /** + * Creates an instance of the switch. + * + * + * @generated + */ + public RegexSwitch() { + if (modelPackage == null) { + modelPackage = RegexPackage.eINSTANCE; + } + } + + /** + * Calls caseXXX for each class of the model until one returns a non null result; it yields that result. + * + * + * @return the first non-null result returned by a caseXXX call. + * @generated + */ + public Object doSwitch(EObject theEObject) { + return doSwitch(theEObject.eClass(), theEObject); + } + + /** + * Calls caseXXX for each class of the model until one returns a non null result; it yields that result. + * + * + * @return the first non-null result returned by a caseXXX call. + * @generated + */ + protected Object doSwitch(EClass theEClass, EObject theEObject) { + if (theEClass.eContainer() == modelPackage) { + return doSwitch(theEClass.getClassifierID(), theEObject); + } + else { + List eSuperTypes = theEClass.getESuperTypes(); + return + eSuperTypes.isEmpty() ? + defaultCase(theEObject) : + doSwitch((EClass)eSuperTypes.get(0), theEObject); + } + } + + /** + * Calls caseXXX for each class of the model until one returns a non null result; it yields that result. + * + * + * @return the first non-null result returned by a caseXXX call. + * @generated + */ + protected Object doSwitch(int classifierID, EObject theEObject) { + switch (classifierID) { + case RegexPackage.EPATTERN: { + EPattern ePattern = (EPattern)theEObject; + Object result = caseEPattern(ePattern); + if (result == null) result = defaultCase(theEObject); + return result; + } + default: return defaultCase(theEObject); + } + } + + /** + * Returns the result of interpretting the object as an instance of 'EPattern'. + * + * This implementation returns null; + * returning a non-null result will terminate the switch. + * + * @param object the target of the switch. + * @return the result of interpretting the object as an instance of 'EPattern'. + * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject) + * @generated + */ + public Object caseEPattern(EPattern object) { + return null; + } + + /** + * Returns the result of interpretting the object as an instance of 'EObject'. + * + * This implementation returns null; + * returning a non-null result will terminate the switch, but this is the last case anyway. + * + * @param object the target of the switch. + * @return the result of interpretting the object as an instance of 'EObject'. + * @see #doSwitch(org.eclipse.emf.ecore.EObject) + * @generated + */ + public Object defaultCase(EObject object) { + return null; + } + +} //RegexSwitch diff --git a/com.ibm.wala.emf/models/wala.ecore b/com.ibm.wala.emf/models/wala.ecore new file mode 100644 index 000000000..e945224a6 --- /dev/null +++ b/com.ibm.wala.emf/models/wala.ecore @@ -0,0 +1,200 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/com.ibm.wala.emf/models/wala.genmodel b/com.ibm.wala.emf/models/wala.genmodel new file mode 100644 index 000000000..d833d9e98 --- /dev/null +++ b/com.ibm.wala.emf/models/wala.genmodel @@ -0,0 +1,176 @@ + + + wala.ecore + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/com.ibm.wala.emf/plugin.properties b/com.ibm.wala.emf/plugin.properties new file mode 100644 index 000000000..847749489 --- /dev/null +++ b/com.ibm.wala.emf/plugin.properties @@ -0,0 +1,20 @@ +# +# +# +# $Id$ + +# ==================================================================== +# To code developer: +# Do NOT change the properties between this line and the +# "%%% END OF TRANSLATED PROPERTIES %%%" line. +# Make a new property name, append to the end of the file and change +# the code to use the new property. +# ==================================================================== + +# ==================================================================== +# %%% END OF TRANSLATED PROPERTIES %%% +# ==================================================================== + +pluginName = Wala Model +providerName = www.example.org + diff --git a/com.ibm.wala.emf/plugin.xml b/com.ibm.wala.emf/plugin.xml new file mode 100644 index 000000000..bed6e9d91 --- /dev/null +++ b/com.ibm.wala.emf/plugin.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + diff --git a/com.ibm.wala.emf/src/com/ibm/wala/ecore/common/CommonFactory.java b/com.ibm.wala.emf/src/com/ibm/wala/ecore/common/CommonFactory.java new file mode 100644 index 000000000..8ce4e1d67 --- /dev/null +++ b/com.ibm.wala.emf/src/com/ibm/wala/ecore/common/CommonFactory.java @@ -0,0 +1,91 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.common; + +import org.eclipse.emf.ecore.EFactory; + +/** + * + * The Factory for the model. + * It provides a create method for each non-abstract class of the model. + * + * @see com.ibm.wala.ecore.common.CommonPackage + * @generated + */ +public interface CommonFactory extends EFactory { + /** + * The singleton instance of the factory. + * + * + * @generated + */ + CommonFactory eINSTANCE = com.ibm.wala.ecore.common.impl.CommonFactoryImpl.init(); + + /** + * Returns a new object of class 'EPair'. + * + * + * @return a new object of class 'EPair'. + * @generated + */ + EPair createEPair(); + + /** + * Returns a new object of class 'ERelation'. + * + * + * @return a new object of class 'ERelation'. + * @generated + */ + ERelation createERelation(); + + /** + * Returns a new object of class 'EContainer'. + * + * + * @return a new object of class 'EContainer'. + * @generated + */ + EContainer createEContainer(); + + /** + * Returns a new object of class 'ENot Container'. + * + * + * @return a new object of class 'ENot Container'. + * @generated + */ + ENotContainer createENotContainer(); + + /** + * Returns a new object of class 'EString Holder'. + * + * + * @return a new object of class 'EString Holder'. + * @generated + */ + EStringHolder createEStringHolder(); + + /** + * Returns a new object of class 'EObject With Container Id'. + * + * + * @return a new object of class 'EObject With Container Id'. + * @generated + */ + EObjectWithContainerId createEObjectWithContainerId(); + + /** + * Returns the package supported by this factory. + * + * + * @return the package supported by this factory. + * @generated + */ + CommonPackage getCommonPackage(); + +} //CommonFactory diff --git a/com.ibm.wala.emf/src/com/ibm/wala/ecore/common/CommonPackage.java b/com.ibm.wala.emf/src/com/ibm/wala/ecore/common/CommonPackage.java new file mode 100644 index 000000000..db5c524cc --- /dev/null +++ b/com.ibm.wala.emf/src/com/ibm/wala/ecore/common/CommonPackage.java @@ -0,0 +1,714 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.common; + +import org.eclipse.emf.ecore.EAttribute; +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EDataType; +import org.eclipse.emf.ecore.EPackage; +import org.eclipse.emf.ecore.EReference; + +/** + * + * The Package for the model. + * It contains accessors for the meta objects to represent + *

                                + *
                              • each class,
                              • + *
                              • each feature of each class,
                              • + *
                              • each enum,
                              • + *
                              • and each data type
                              • + *
                              + * + * @see com.ibm.wala.ecore.common.CommonFactory + * @model kind="package" + * @generated + */ +public interface CommonPackage extends EPackage { + /** + * The package name. + * + * + * @generated + */ + String eNAME = "common"; + + /** + * The package namespace URI. + * + * + * @generated + */ + String eNS_URI = "http:///com/ibm/wala/wala.ecore.common"; + + /** + * The package namespace name. + * + * + * @generated + */ + String eNS_PREFIX = "com.ibm.wala.common"; + + /** + * The singleton instance of the package. + * + * + * @generated + */ + CommonPackage eINSTANCE = com.ibm.wala.ecore.common.impl.CommonPackageImpl.init(); + + /** + * The meta object id for the '{@link com.ibm.wala.ecore.common.ECollection ECollection}' class. + * + * + * @see com.ibm.wala.ecore.common.ECollection + * @see com.ibm.wala.ecore.common.impl.CommonPackageImpl#getECollection() + * @generated + */ + int ECOLLECTION = 0; + + /** + * The feature id for the 'Contents' reference list. + * + * + * @generated + * @ordered + */ + int ECOLLECTION__CONTENTS = 0; + + /** + * The number of structural features of the 'ECollection' class. + * + * + * @generated + * @ordered + */ + int ECOLLECTION_FEATURE_COUNT = 1; + + /** + * The meta object id for the '{@link com.ibm.wala.ecore.common.impl.EPairImpl EPair}' class. + * + * + * @see com.ibm.wala.ecore.common.impl.EPairImpl + * @see com.ibm.wala.ecore.common.impl.CommonPackageImpl#getEPair() + * @generated + */ + int EPAIR = 1; + + /** + * The feature id for the 'X' reference. + * + * + * @generated + * @ordered + */ + int EPAIR__X = 0; + + /** + * The feature id for the 'Y' reference. + * + * + * @generated + * @ordered + */ + int EPAIR__Y = 1; + + /** + * The number of structural features of the 'EPair' class. + * + * + * @generated + * @ordered + */ + int EPAIR_FEATURE_COUNT = 2; + + /** + * The meta object id for the '{@link com.ibm.wala.ecore.common.impl.EContainerImpl EContainer}' class. + * + * + * @see com.ibm.wala.ecore.common.impl.EContainerImpl + * @see com.ibm.wala.ecore.common.impl.CommonPackageImpl#getEContainer() + * @generated + */ + int ECONTAINER = 3; + + /** + * The feature id for the 'Contents' reference list. + * + * + * @generated + * @ordered + */ + int ECONTAINER__CONTENTS = ECOLLECTION__CONTENTS; + + /** + * The feature id for the 'Containees' containment reference list. + * + * + * @generated + * @ordered + */ + int ECONTAINER__CONTAINEES = ECOLLECTION_FEATURE_COUNT + 0; + + /** + * The number of structural features of the 'EContainer' class. + * + * + * @generated + * @ordered + */ + int ECONTAINER_FEATURE_COUNT = ECOLLECTION_FEATURE_COUNT + 1; + + /** + * The meta object id for the '{@link com.ibm.wala.ecore.common.impl.ERelationImpl ERelation}' class. + * + * + * @see com.ibm.wala.ecore.common.impl.ERelationImpl + * @see com.ibm.wala.ecore.common.impl.CommonPackageImpl#getERelation() + * @generated + */ + int ERELATION = 2; + + /** + * The feature id for the 'Contents' reference list. + * + * + * @generated + * @ordered + */ + int ERELATION__CONTENTS = ECONTAINER__CONTENTS; + + /** + * The feature id for the 'Containees' containment reference list. + * + * + * @generated + * @ordered + */ + int ERELATION__CONTAINEES = ECONTAINER__CONTAINEES; + + /** + * The feature id for the 'Name' attribute. + * + * + * @generated + * @ordered + */ + int ERELATION__NAME = ECONTAINER_FEATURE_COUNT + 0; + + /** + * The number of structural features of the 'ERelation' class. + * + * + * @generated + * @ordered + */ + int ERELATION_FEATURE_COUNT = ECONTAINER_FEATURE_COUNT + 1; + + /** + * The meta object id for the '{@link com.ibm.wala.ecore.common.impl.ENotContainerImpl ENot Container}' class. + * + * + * @see com.ibm.wala.ecore.common.impl.ENotContainerImpl + * @see com.ibm.wala.ecore.common.impl.CommonPackageImpl#getENotContainer() + * @generated + */ + int ENOT_CONTAINER = 4; + + /** + * The feature id for the 'Contents' reference list. + * + * + * @generated + * @ordered + */ + int ENOT_CONTAINER__CONTENTS = ECOLLECTION__CONTENTS; + + /** + * The feature id for the 'Elements' reference list. + * + * + * @generated + * @ordered + */ + int ENOT_CONTAINER__ELEMENTS = ECOLLECTION_FEATURE_COUNT + 0; + + /** + * The number of structural features of the 'ENot Container' class. + * + * + * @generated + * @ordered + */ + int ENOT_CONTAINER_FEATURE_COUNT = ECOLLECTION_FEATURE_COUNT + 1; + + /** + * The meta object id for the '{@link com.ibm.wala.ecore.common.impl.EStringHolderImpl EString Holder}' class. + * + * + * @see com.ibm.wala.ecore.common.impl.EStringHolderImpl + * @see com.ibm.wala.ecore.common.impl.CommonPackageImpl#getEStringHolder() + * @generated + */ + int ESTRING_HOLDER = 5; + + /** + * The feature id for the 'Value' attribute. + * + * + * @generated + * @ordered + */ + int ESTRING_HOLDER__VALUE = 0; + + /** + * The number of structural features of the 'EString Holder' class. + * + * + * @generated + * @ordered + */ + int ESTRING_HOLDER_FEATURE_COUNT = 1; + + /** + * The meta object id for the '{@link com.ibm.wala.ecore.common.impl.EObjectWithContainerIdImpl EObject With Container Id}' class. + * + * + * @see com.ibm.wala.ecore.common.impl.EObjectWithContainerIdImpl + * @see com.ibm.wala.ecore.common.impl.CommonPackageImpl#getEObjectWithContainerId() + * @generated + */ + int EOBJECT_WITH_CONTAINER_ID = 6; + + /** + * The feature id for the 'Id' attribute. + * + * + * @generated + * @ordered + */ + int EOBJECT_WITH_CONTAINER_ID__ID = 0; + + /** + * The number of structural features of the 'EObject With Container Id' class. + * + * + * @generated + * @ordered + */ + int EOBJECT_WITH_CONTAINER_ID_FEATURE_COUNT = 1; + + /** + * The meta object id for the 'EJava Collection' data type. + * + * + * @see java.util.Collection + * @see com.ibm.wala.ecore.common.impl.CommonPackageImpl#getEJavaCollection() + * @generated + */ + int EJAVA_COLLECTION = 7; + + /** + * The meta object id for the 'EFile' data type. + * + * + * @see java.io.File + * @see com.ibm.wala.ecore.common.impl.CommonPackageImpl#getEFile() + * @generated + */ + int EFILE = 8; + + /** + * The meta object id for the 'EIterator' data type. + * + * + * @see java.util.Iterator + * @see com.ibm.wala.ecore.common.impl.CommonPackageImpl#getEIterator() + * @generated + */ + int EITERATOR = 9; + + + /** + * Returns the meta object for class '{@link com.ibm.wala.ecore.common.ECollection ECollection}'. + * + * + * @return the meta object for class 'ECollection'. + * @see com.ibm.wala.ecore.common.ECollection + * @generated + */ + EClass getECollection(); + + /** + * Returns the meta object for the reference list '{@link com.ibm.wala.ecore.common.ECollection#getContents Contents}'. + * + * + * @return the meta object for the reference list 'Contents'. + * @see com.ibm.wala.ecore.common.ECollection#getContents() + * @see #getECollection() + * @generated + */ + EReference getECollection_Contents(); + + /** + * Returns the meta object for class '{@link com.ibm.wala.ecore.common.EPair EPair}'. + * + * + * @return the meta object for class 'EPair'. + * @see com.ibm.wala.ecore.common.EPair + * @generated + */ + EClass getEPair(); + + /** + * Returns the meta object for the reference '{@link com.ibm.wala.ecore.common.EPair#getX X}'. + * + * + * @return the meta object for the reference 'X'. + * @see com.ibm.wala.ecore.common.EPair#getX() + * @see #getEPair() + * @generated + */ + EReference getEPair_X(); + + /** + * Returns the meta object for the reference '{@link com.ibm.wala.ecore.common.EPair#getY Y}'. + * + * + * @return the meta object for the reference 'Y'. + * @see com.ibm.wala.ecore.common.EPair#getY() + * @see #getEPair() + * @generated + */ + EReference getEPair_Y(); + + /** + * Returns the meta object for class '{@link com.ibm.wala.ecore.common.ERelation ERelation}'. + * + * + * @return the meta object for class 'ERelation'. + * @see com.ibm.wala.ecore.common.ERelation + * @generated + */ + EClass getERelation(); + + /** + * Returns the meta object for the attribute '{@link com.ibm.wala.ecore.common.ERelation#getName Name}'. + * + * + * @return the meta object for the attribute 'Name'. + * @see com.ibm.wala.ecore.common.ERelation#getName() + * @see #getERelation() + * @generated + */ + EAttribute getERelation_Name(); + + /** + * Returns the meta object for class '{@link com.ibm.wala.ecore.common.EContainer EContainer}'. + * + * + * @return the meta object for class 'EContainer'. + * @see com.ibm.wala.ecore.common.EContainer + * @generated + */ + EClass getEContainer(); + + /** + * Returns the meta object for the containment reference list '{@link com.ibm.wala.ecore.common.EContainer#getContainees Containees}'. + * + * + * @return the meta object for the containment reference list 'Containees'. + * @see com.ibm.wala.ecore.common.EContainer#getContainees() + * @see #getEContainer() + * @generated + */ + EReference getEContainer_Containees(); + + /** + * Returns the meta object for class '{@link com.ibm.wala.ecore.common.ENotContainer ENot Container}'. + * + * + * @return the meta object for class 'ENot Container'. + * @see com.ibm.wala.ecore.common.ENotContainer + * @generated + */ + EClass getENotContainer(); + + /** + * Returns the meta object for the reference list '{@link com.ibm.wala.ecore.common.ENotContainer#getElements Elements}'. + * + * + * @return the meta object for the reference list 'Elements'. + * @see com.ibm.wala.ecore.common.ENotContainer#getElements() + * @see #getENotContainer() + * @generated + */ + EReference getENotContainer_Elements(); + + /** + * Returns the meta object for class '{@link com.ibm.wala.ecore.common.EStringHolder EString Holder}'. + * + * + * @return the meta object for class 'EString Holder'. + * @see com.ibm.wala.ecore.common.EStringHolder + * @generated + */ + EClass getEStringHolder(); + + /** + * Returns the meta object for the attribute '{@link com.ibm.wala.ecore.common.EStringHolder#getValue Value}'. + * + * + * @return the meta object for the attribute 'Value'. + * @see com.ibm.wala.ecore.common.EStringHolder#getValue() + * @see #getEStringHolder() + * @generated + */ + EAttribute getEStringHolder_Value(); + + /** + * Returns the meta object for class '{@link com.ibm.wala.ecore.common.EObjectWithContainerId EObject With Container Id}'. + * + * + * @return the meta object for class 'EObject With Container Id'. + * @see com.ibm.wala.ecore.common.EObjectWithContainerId + * @generated + */ + EClass getEObjectWithContainerId(); + + /** + * Returns the meta object for the attribute '{@link com.ibm.wala.ecore.common.EObjectWithContainerId#getId Id}'. + * + * + * @return the meta object for the attribute 'Id'. + * @see com.ibm.wala.ecore.common.EObjectWithContainerId#getId() + * @see #getEObjectWithContainerId() + * @generated + */ + EAttribute getEObjectWithContainerId_Id(); + + /** + * Returns the meta object for data type '{@link java.util.Collection EJava Collection}'. + * + * + * @return the meta object for data type 'EJava Collection'. + * @see java.util.Collection + * @model instanceClass="java.util.Collection" serializable="false" + * @generated + */ + EDataType getEJavaCollection(); + + /** + * Returns the meta object for data type '{@link java.io.File EFile}'. + * + * + * @return the meta object for data type 'EFile'. + * @see java.io.File + * @model instanceClass="java.io.File" serializable="false" + * @generated + */ + EDataType getEFile(); + + /** + * Returns the meta object for data type '{@link java.util.Iterator EIterator}'. + * + * + * @return the meta object for data type 'EIterator'. + * @see java.util.Iterator + * @model instanceClass="java.util.Iterator" serializable="false" + * @generated + */ + EDataType getEIterator(); + + /** + * Returns the factory that creates the instances of the model. + * + * + * @return the factory that creates the instances of the model. + * @generated + */ + CommonFactory getCommonFactory(); + + /** + * + * Defines literals for the meta objects that represent + *
                                + *
                              • each class,
                              • + *
                              • each feature of each class,
                              • + *
                              • each enum,
                              • + *
                              • and each data type
                              • + *
                              + * + * @generated + */ + interface Literals { + /** + * The meta object literal for the '{@link com.ibm.wala.ecore.common.ECollection ECollection}' class. + * + * + * @see com.ibm.wala.ecore.common.ECollection + * @see com.ibm.wala.ecore.common.impl.CommonPackageImpl#getECollection() + * @generated + */ + EClass ECOLLECTION = eINSTANCE.getECollection(); + + /** + * The meta object literal for the 'Contents' reference list feature. + * + * + * @generated + */ + EReference ECOLLECTION__CONTENTS = eINSTANCE.getECollection_Contents(); + + /** + * The meta object literal for the '{@link com.ibm.wala.ecore.common.impl.EPairImpl EPair}' class. + * + * + * @see com.ibm.wala.ecore.common.impl.EPairImpl + * @see com.ibm.wala.ecore.common.impl.CommonPackageImpl#getEPair() + * @generated + */ + EClass EPAIR = eINSTANCE.getEPair(); + + /** + * The meta object literal for the 'X' reference feature. + * + * + * @generated + */ + EReference EPAIR__X = eINSTANCE.getEPair_X(); + + /** + * The meta object literal for the 'Y' reference feature. + * + * + * @generated + */ + EReference EPAIR__Y = eINSTANCE.getEPair_Y(); + + /** + * The meta object literal for the '{@link com.ibm.wala.ecore.common.impl.ERelationImpl ERelation}' class. + * + * + * @see com.ibm.wala.ecore.common.impl.ERelationImpl + * @see com.ibm.wala.ecore.common.impl.CommonPackageImpl#getERelation() + * @generated + */ + EClass ERELATION = eINSTANCE.getERelation(); + + /** + * The meta object literal for the 'Name' attribute feature. + * + * + * @generated + */ + EAttribute ERELATION__NAME = eINSTANCE.getERelation_Name(); + + /** + * The meta object literal for the '{@link com.ibm.wala.ecore.common.impl.EContainerImpl EContainer}' class. + * + * + * @see com.ibm.wala.ecore.common.impl.EContainerImpl + * @see com.ibm.wala.ecore.common.impl.CommonPackageImpl#getEContainer() + * @generated + */ + EClass ECONTAINER = eINSTANCE.getEContainer(); + + /** + * The meta object literal for the 'Containees' containment reference list feature. + * + * + * @generated + */ + EReference ECONTAINER__CONTAINEES = eINSTANCE.getEContainer_Containees(); + + /** + * The meta object literal for the '{@link com.ibm.wala.ecore.common.impl.ENotContainerImpl ENot Container}' class. + * + * + * @see com.ibm.wala.ecore.common.impl.ENotContainerImpl + * @see com.ibm.wala.ecore.common.impl.CommonPackageImpl#getENotContainer() + * @generated + */ + EClass ENOT_CONTAINER = eINSTANCE.getENotContainer(); + + /** + * The meta object literal for the 'Elements' reference list feature. + * + * + * @generated + */ + EReference ENOT_CONTAINER__ELEMENTS = eINSTANCE.getENotContainer_Elements(); + + /** + * The meta object literal for the '{@link com.ibm.wala.ecore.common.impl.EStringHolderImpl EString Holder}' class. + * + * + * @see com.ibm.wala.ecore.common.impl.EStringHolderImpl + * @see com.ibm.wala.ecore.common.impl.CommonPackageImpl#getEStringHolder() + * @generated + */ + EClass ESTRING_HOLDER = eINSTANCE.getEStringHolder(); + + /** + * The meta object literal for the 'Value' attribute feature. + * + * + * @generated + */ + EAttribute ESTRING_HOLDER__VALUE = eINSTANCE.getEStringHolder_Value(); + + /** + * The meta object literal for the '{@link com.ibm.wala.ecore.common.impl.EObjectWithContainerIdImpl EObject With Container Id}' class. + * + * + * @see com.ibm.wala.ecore.common.impl.EObjectWithContainerIdImpl + * @see com.ibm.wala.ecore.common.impl.CommonPackageImpl#getEObjectWithContainerId() + * @generated + */ + EClass EOBJECT_WITH_CONTAINER_ID = eINSTANCE.getEObjectWithContainerId(); + + /** + * The meta object literal for the 'Id' attribute feature. + * + * + * @generated + */ + EAttribute EOBJECT_WITH_CONTAINER_ID__ID = eINSTANCE.getEObjectWithContainerId_Id(); + + /** + * The meta object literal for the 'EJava Collection' data type. + * + * + * @see java.util.Collection + * @see com.ibm.wala.ecore.common.impl.CommonPackageImpl#getEJavaCollection() + * @generated + */ + EDataType EJAVA_COLLECTION = eINSTANCE.getEJavaCollection(); + + /** + * The meta object literal for the 'EFile' data type. + * + * + * @see java.io.File + * @see com.ibm.wala.ecore.common.impl.CommonPackageImpl#getEFile() + * @generated + */ + EDataType EFILE = eINSTANCE.getEFile(); + + /** + * The meta object literal for the 'EIterator' data type. + * + * + * @see java.util.Iterator + * @see com.ibm.wala.ecore.common.impl.CommonPackageImpl#getEIterator() + * @generated + */ + EDataType EITERATOR = eINSTANCE.getEIterator(); + + } + +} //CommonPackage diff --git a/com.ibm.wala.emf/src/com/ibm/wala/ecore/common/ECollection.java b/com.ibm.wala.emf/src/com/ibm/wala/ecore/common/ECollection.java new file mode 100644 index 000000000..fd6493a00 --- /dev/null +++ b/com.ibm.wala.emf/src/com/ibm/wala/ecore/common/ECollection.java @@ -0,0 +1,46 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.common; + +import org.eclipse.emf.common.util.EList; + +import org.eclipse.emf.ecore.EObject; + +/** + * + * A representation of the model object 'ECollection'. + * + * + *

                              + * The following features are supported: + *

                                + *
                              • {@link com.ibm.wala.ecore.common.ECollection#getContents Contents}
                              • + *
                              + *

                              + * + * @see com.ibm.wala.ecore.common.CommonPackage#getECollection() + * @model interface="true" abstract="true" + * @generated + */ +public interface ECollection extends EObject { + /** + * Returns the value of the 'Contents' reference list. + * The list contents are of type {@link org.eclipse.emf.ecore.EObject}. + * + *

                              + * If the meaning of the 'Contents' reference list isn't clear, + * there really should be more of a description here... + *

                              + * + * @return the value of the 'Contents' reference list. + * @see com.ibm.wala.ecore.common.CommonPackage#getECollection_Contents() + * @model type="org.eclipse.emf.ecore.EObject" transient="true" volatile="true" + * @generated + */ + EList getContents(); + +} // ECollection \ No newline at end of file diff --git a/com.ibm.wala.emf/src/com/ibm/wala/ecore/common/EContainer.java b/com.ibm.wala.emf/src/com/ibm/wala/ecore/common/EContainer.java new file mode 100644 index 000000000..66e3a7b75 --- /dev/null +++ b/com.ibm.wala.emf/src/com/ibm/wala/ecore/common/EContainer.java @@ -0,0 +1,44 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.common; + +import org.eclipse.emf.common.util.EList; + +/** + * + * A representation of the model object 'EContainer'. + * + * + *

                              + * The following features are supported: + *

                                + *
                              • {@link com.ibm.wala.ecore.common.EContainer#getContainees Containees}
                              • + *
                              + *

                              + * + * @see com.ibm.wala.ecore.common.CommonPackage#getEContainer() + * @model + * @generated + */ +public interface EContainer extends ECollection { + /** + * Returns the value of the 'Containees' containment reference list. + * The list contents are of type {@link org.eclipse.emf.ecore.EObject}. + * + *

                              + * If the meaning of the 'Containees' containment reference list isn't clear, + * there really should be more of a description here... + *

                              + * + * @return the value of the 'Containees' containment reference list. + * @see com.ibm.wala.ecore.common.CommonPackage#getEContainer_Containees() + * @model type="org.eclipse.emf.ecore.EObject" containment="true" + * @generated + */ + EList getContainees(); + +} // EContainer \ No newline at end of file diff --git a/com.ibm.wala.emf/src/com/ibm/wala/ecore/common/ENotContainer.java b/com.ibm.wala.emf/src/com/ibm/wala/ecore/common/ENotContainer.java new file mode 100644 index 000000000..ca4382c1f --- /dev/null +++ b/com.ibm.wala.emf/src/com/ibm/wala/ecore/common/ENotContainer.java @@ -0,0 +1,44 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.common; + +import org.eclipse.emf.common.util.EList; + +/** + * + * A representation of the model object 'ENot Container'. + * + * + *

                              + * The following features are supported: + *

                                + *
                              • {@link com.ibm.wala.ecore.common.ENotContainer#getElements Elements}
                              • + *
                              + *

                              + * + * @see com.ibm.wala.ecore.common.CommonPackage#getENotContainer() + * @model + * @generated + */ +public interface ENotContainer extends ECollection { + /** + * Returns the value of the 'Elements' reference list. + * The list contents are of type {@link org.eclipse.emf.ecore.EObject}. + * + *

                              + * If the meaning of the 'Elements' reference list isn't clear, + * there really should be more of a description here... + *

                              + * + * @return the value of the 'Elements' reference list. + * @see com.ibm.wala.ecore.common.CommonPackage#getENotContainer_Elements() + * @model type="org.eclipse.emf.ecore.EObject" + * @generated + */ + EList getElements(); + +} // ENotContainer \ No newline at end of file diff --git a/com.ibm.wala.emf/src/com/ibm/wala/ecore/common/EObjectWithContainerId.java b/com.ibm.wala.emf/src/com/ibm/wala/ecore/common/EObjectWithContainerId.java new file mode 100644 index 000000000..f8c2d2d43 --- /dev/null +++ b/com.ibm.wala.emf/src/com/ibm/wala/ecore/common/EObjectWithContainerId.java @@ -0,0 +1,55 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.common; + +import org.eclipse.emf.ecore.EObject; + +/** + * + * A representation of the model object 'EObject With Container Id'. + * + * + *

                              + * The following features are supported: + *

                                + *
                              • {@link com.ibm.wala.ecore.common.EObjectWithContainerId#getId Id}
                              • + *
                              + *

                              + * + * @see com.ibm.wala.ecore.common.CommonPackage#getEObjectWithContainerId() + * @model + * @generated + */ +public interface EObjectWithContainerId extends EObject { + /** + * Returns the value of the 'Id' attribute. + * The default value is "-1". + * + *

                              + * If the meaning of the 'Id' attribute isn't clear, + * there really should be more of a description here... + *

                              + * + * @return the value of the 'Id' attribute. + * @see #setId(int) + * @see com.ibm.wala.ecore.common.CommonPackage#getEObjectWithContainerId_Id() + * @model default="-1" id="true" required="true" + * @generated + */ + int getId(); + + /** + * Sets the value of the '{@link com.ibm.wala.ecore.common.EObjectWithContainerId#getId Id}' attribute. + * + * + * @param value the new value of the 'Id' attribute. + * @see #getId() + * @generated + */ + void setId(int value); + +} // EObjectWithContainerId \ No newline at end of file diff --git a/com.ibm.wala.emf/src/com/ibm/wala/ecore/common/EPair.java b/com.ibm.wala.emf/src/com/ibm/wala/ecore/common/EPair.java new file mode 100644 index 000000000..ee9b22528 --- /dev/null +++ b/com.ibm.wala.emf/src/com/ibm/wala/ecore/common/EPair.java @@ -0,0 +1,81 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.common; + +import org.eclipse.emf.ecore.EObject; + +/** + * + * A representation of the model object 'EPair'. + * + * + *

                              + * The following features are supported: + *

                                + *
                              • {@link com.ibm.wala.ecore.common.EPair#getX X}
                              • + *
                              • {@link com.ibm.wala.ecore.common.EPair#getY Y}
                              • + *
                              + *

                              + * + * @see com.ibm.wala.ecore.common.CommonPackage#getEPair() + * @model + * @generated + */ +public interface EPair extends EObject { + /** + * Returns the value of the 'X' reference. + * + *

                              + * If the meaning of the 'X' reference isn't clear, + * there really should be more of a description here... + *

                              + * + * @return the value of the 'X' reference. + * @see #setX(EObject) + * @see com.ibm.wala.ecore.common.CommonPackage#getEPair_X() + * @model required="true" + * @generated + */ + EObject getX(); + + /** + * Sets the value of the '{@link com.ibm.wala.ecore.common.EPair#getX X}' reference. + * + * + * @param value the new value of the 'X' reference. + * @see #getX() + * @generated + */ + void setX(EObject value); + + /** + * Returns the value of the 'Y' reference. + * + *

                              + * If the meaning of the 'Y' reference isn't clear, + * there really should be more of a description here... + *

                              + * + * @return the value of the 'Y' reference. + * @see #setY(EObject) + * @see com.ibm.wala.ecore.common.CommonPackage#getEPair_Y() + * @model required="true" + * @generated + */ + EObject getY(); + + /** + * Sets the value of the '{@link com.ibm.wala.ecore.common.EPair#getY Y}' reference. + * + * + * @param value the new value of the 'Y' reference. + * @see #getY() + * @generated + */ + void setY(EObject value); + +} // EPair \ No newline at end of file diff --git a/com.ibm.wala.emf/src/com/ibm/wala/ecore/common/ERelation.java b/com.ibm.wala.emf/src/com/ibm/wala/ecore/common/ERelation.java new file mode 100644 index 000000000..9f52a6004 --- /dev/null +++ b/com.ibm.wala.emf/src/com/ibm/wala/ecore/common/ERelation.java @@ -0,0 +1,53 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.common; + + +/** + * + * A representation of the model object 'ERelation'. + * + * + *

                              + * The following features are supported: + *

                                + *
                              • {@link com.ibm.wala.ecore.common.ERelation#getName Name}
                              • + *
                              + *

                              + * + * @see com.ibm.wala.ecore.common.CommonPackage#getERelation() + * @model + * @generated + */ +public interface ERelation extends EContainer { + /** + * Returns the value of the 'Name' attribute. + * + *

                              + * If the meaning of the 'Name' attribute isn't clear, + * there really should be more of a description here... + *

                              + * + * @return the value of the 'Name' attribute. + * @see #setName(String) + * @see com.ibm.wala.ecore.common.CommonPackage#getERelation_Name() + * @model + * @generated + */ + String getName(); + + /** + * Sets the value of the '{@link com.ibm.wala.ecore.common.ERelation#getName Name}' attribute. + * + * + * @param value the new value of the 'Name' attribute. + * @see #getName() + * @generated + */ + void setName(String value); + +} // ERelation \ No newline at end of file diff --git a/com.ibm.wala.emf/src/com/ibm/wala/ecore/common/EStringHolder.java b/com.ibm.wala.emf/src/com/ibm/wala/ecore/common/EStringHolder.java new file mode 100644 index 000000000..606b59a9e --- /dev/null +++ b/com.ibm.wala.emf/src/com/ibm/wala/ecore/common/EStringHolder.java @@ -0,0 +1,54 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.common; + +import org.eclipse.emf.ecore.EObject; + +/** + * + * A representation of the model object 'EString Holder'. + * + * + *

                              + * The following features are supported: + *

                                + *
                              • {@link com.ibm.wala.ecore.common.EStringHolder#getValue Value}
                              • + *
                              + *

                              + * + * @see com.ibm.wala.ecore.common.CommonPackage#getEStringHolder() + * @model + * @generated + */ +public interface EStringHolder extends EObject { + /** + * Returns the value of the 'Value' attribute. + * + *

                              + * If the meaning of the 'Value' attribute isn't clear, + * there really should be more of a description here... + *

                              + * + * @return the value of the 'Value' attribute. + * @see #setValue(String) + * @see com.ibm.wala.ecore.common.CommonPackage#getEStringHolder_Value() + * @model required="true" + * @generated + */ + String getValue(); + + /** + * Sets the value of the '{@link com.ibm.wala.ecore.common.EStringHolder#getValue Value}' attribute. + * + * + * @param value the new value of the 'Value' attribute. + * @see #getValue() + * @generated + */ + void setValue(String value); + +} // EStringHolder \ No newline at end of file diff --git a/com.ibm.wala.emf/src/com/ibm/wala/ecore/common/impl/CommonFactoryImpl.java b/com.ibm.wala.emf/src/com/ibm/wala/ecore/common/impl/CommonFactoryImpl.java new file mode 100644 index 000000000..2eac2e2e4 --- /dev/null +++ b/com.ibm.wala.emf/src/com/ibm/wala/ecore/common/impl/CommonFactoryImpl.java @@ -0,0 +1,177 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.common.impl; + +import com.ibm.wala.ecore.common.*; + +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EDataType; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EPackage; + +import org.eclipse.emf.ecore.impl.EFactoryImpl; + +import org.eclipse.emf.ecore.plugin.EcorePlugin; + +/** + * + * An implementation of the model Factory. + * + * @generated + */ +public class CommonFactoryImpl extends EFactoryImpl implements CommonFactory { + /** + * Creates the default factory implementation. + * + * + * @generated + */ + public static CommonFactory init() { + try { + CommonFactory theCommonFactory = (CommonFactory)EPackage.Registry.INSTANCE.getEFactory("http:///com/ibm/wala/wala.ecore.common"); + if (theCommonFactory != null) { + return theCommonFactory; + } + } + catch (Exception exception) { + EcorePlugin.INSTANCE.log(exception); + } + return new CommonFactoryImpl(); + } + + /** + * Creates an instance of the factory. + * + * + * @generated + */ + public CommonFactoryImpl() { + super(); + } + + /** + * + * + * @generated + */ + public EObject create(EClass eClass) { + switch (eClass.getClassifierID()) { + case CommonPackage.EPAIR: return createEPair(); + case CommonPackage.ERELATION: return createERelation(); + case CommonPackage.ECONTAINER: return createEContainer(); + case CommonPackage.ENOT_CONTAINER: return createENotContainer(); + case CommonPackage.ESTRING_HOLDER: return createEStringHolder(); + case CommonPackage.EOBJECT_WITH_CONTAINER_ID: return createEObjectWithContainerId(); + default: + throw new IllegalArgumentException("The class '" + eClass.getName() + "' is not a valid classifier"); + } + } + + /** + * + * + * @generated + */ + public Object createFromString(EDataType eDataType, String initialValue) { + switch (eDataType.getClassifierID()) { + default: + throw new IllegalArgumentException("The datatype '" + eDataType.getName() + "' is not a valid classifier"); + } + } + + /** + * + * + * @generated + */ + public String convertToString(EDataType eDataType, Object instanceValue) { + switch (eDataType.getClassifierID()) { + default: + throw new IllegalArgumentException("The datatype '" + eDataType.getName() + "' is not a valid classifier"); + } + } + + /** + * + * + * @generated + */ + public EPair createEPair() { + EPairImpl ePair = new EPairImpl(); + return ePair; + } + + /** + * + * + * @generated + */ + public ERelation createERelation() { + ERelationImpl eRelation = new ERelationImpl(); + return eRelation; + } + + /** + * + * + * @generated + */ + public EContainer createEContainer() { + EContainerImpl eContainer = new EContainerImpl(); + return eContainer; + } + + /** + * + * + * @generated + */ + public ENotContainer createENotContainer() { + ENotContainerImpl eNotContainer = new ENotContainerImpl(); + return eNotContainer; + } + + /** + * + * + * @generated + */ + public EStringHolder createEStringHolder() { + EStringHolderImpl eStringHolder = new EStringHolderImpl(); + return eStringHolder; + } + + /** + * + * + * @generated + */ + public EObjectWithContainerId createEObjectWithContainerId() { + EObjectWithContainerIdImpl eObjectWithContainerId = new EObjectWithContainerIdImpl(); + return eObjectWithContainerId; + } + + /** + * + * + * @generated + */ + public CommonPackage getCommonPackage() { + return (CommonPackage)getEPackage(); + } + + /** + * + * + * @deprecated + * @generated + */ + public static CommonPackage getPackage() { + return CommonPackage.eINSTANCE; + } + +} //CommonFactoryImpl diff --git a/com.ibm.wala.emf/src/com/ibm/wala/ecore/common/impl/CommonPackageImpl.java b/com.ibm.wala.emf/src/com/ibm/wala/ecore/common/impl/CommonPackageImpl.java new file mode 100644 index 000000000..7089e7778 --- /dev/null +++ b/com.ibm.wala.emf/src/com/ibm/wala/ecore/common/impl/CommonPackageImpl.java @@ -0,0 +1,513 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.common.impl; + +import com.ibm.wala.ecore.common.CommonFactory; +import com.ibm.wala.ecore.common.CommonPackage; +import com.ibm.wala.ecore.common.ECollection; +import com.ibm.wala.ecore.common.EContainer; +import com.ibm.wala.ecore.common.ENotContainer; +import com.ibm.wala.ecore.common.EObjectWithContainerId; +import com.ibm.wala.ecore.common.EPair; +import com.ibm.wala.ecore.common.ERelation; +import com.ibm.wala.ecore.common.EStringHolder; + +import com.ibm.wala.ecore.graph.GraphPackage; + +import com.ibm.wala.ecore.graph.impl.GraphPackageImpl; + +import com.ibm.wala.ecore.j2ee.scope.J2EEScopePackage; + +import com.ibm.wala.ecore.j2ee.scope.impl.J2EEScopePackageImpl; + +import com.ibm.wala.ecore.java.JavaPackage; + +import com.ibm.wala.ecore.java.callGraph.CallGraphPackage; + +import com.ibm.wala.ecore.java.callGraph.impl.CallGraphPackageImpl; + +import com.ibm.wala.ecore.java.impl.JavaPackageImpl; + +import com.ibm.wala.ecore.java.pointerAnalysis.PointerAnalysisPackage; + +import com.ibm.wala.ecore.java.pointerAnalysis.impl.PointerAnalysisPackageImpl; + +import com.ibm.wala.ecore.java.scope.JavaScopePackage; + +import com.ibm.wala.ecore.java.scope.impl.JavaScopePackageImpl; + +import com.ibm.wala.ecore.perf.PerfPackage; + +import com.ibm.wala.ecore.perf.impl.PerfPackageImpl; + +import com.ibm.wala.ecore.regex.RegexPackage; + +import com.ibm.wala.ecore.regex.impl.RegexPackageImpl; + +import java.io.File; + +import java.util.Collection; +import java.util.Iterator; + +import org.eclipse.emf.ecore.EAttribute; +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EDataType; +import org.eclipse.emf.ecore.EPackage; +import org.eclipse.emf.ecore.EReference; + +import org.eclipse.emf.ecore.impl.EPackageImpl; + +/** + * + * An implementation of the model Package. + * + * @generated + */ +public class CommonPackageImpl extends EPackageImpl implements CommonPackage { + /** + * + * + * @generated + */ + private EClass eCollectionEClass = null; + + /** + * + * + * @generated + */ + private EClass ePairEClass = null; + + /** + * + * + * @generated + */ + private EClass eRelationEClass = null; + + /** + * + * + * @generated + */ + private EClass eContainerEClass = null; + + /** + * + * + * @generated + */ + private EClass eNotContainerEClass = null; + + /** + * + * + * @generated + */ + private EClass eStringHolderEClass = null; + + /** + * + * + * @generated + */ + private EClass eObjectWithContainerIdEClass = null; + + /** + * + * + * @generated + */ + private EDataType eJavaCollectionEDataType = null; + + /** + * + * + * @generated + */ + private EDataType eFileEDataType = null; + + /** + * + * + * @generated + */ + private EDataType eIteratorEDataType = null; + + /** + * Creates an instance of the model Package, registered with + * {@link org.eclipse.emf.ecore.EPackage.Registry EPackage.Registry} by the package + * package URI value. + *

                              Note: the correct way to create the package is via the static + * factory method {@link #init init()}, which also performs + * initialization of the package, or returns the registered package, + * if one already exists. + * + * + * @see org.eclipse.emf.ecore.EPackage.Registry + * @see com.ibm.wala.ecore.common.CommonPackage#eNS_URI + * @see #init() + * @generated + */ + private CommonPackageImpl() { + super(eNS_URI, CommonFactory.eINSTANCE); + } + + /** + * + * + * @generated + */ + private static boolean isInited = false; + + /** + * Creates, registers, and initializes the Package for this + * model, and for any others upon which it depends. Simple + * dependencies are satisfied by calling this method on all + * dependent packages before doing anything else. This method drives + * initialization for interdependent packages directly, in parallel + * with this package, itself. + *

                              Of this package and its interdependencies, all packages which + * have not yet been registered by their URI values are first created + * and registered. The packages are then initialized in two steps: + * meta-model objects for all of the packages are created before any + * are initialized, since one package's meta-model objects may refer to + * those of another. + *

                              Invocation of this method will not affect any packages that have + * already been initialized. + * + * + * @see #eNS_URI + * @see #createPackageContents() + * @see #initializePackageContents() + * @generated + */ + public static CommonPackage init() { + if (isInited) return (CommonPackage)EPackage.Registry.INSTANCE.getEPackage(CommonPackage.eNS_URI); + + // Obtain or create and register package + CommonPackageImpl theCommonPackage = (CommonPackageImpl)(EPackage.Registry.INSTANCE.getEPackage(eNS_URI) instanceof CommonPackageImpl ? EPackage.Registry.INSTANCE.getEPackage(eNS_URI) : new CommonPackageImpl()); + + isInited = true; + + // Obtain or create and register interdependencies + GraphPackageImpl theGraphPackage = (GraphPackageImpl)(EPackage.Registry.INSTANCE.getEPackage(GraphPackage.eNS_URI) instanceof GraphPackageImpl ? EPackage.Registry.INSTANCE.getEPackage(GraphPackage.eNS_URI) : GraphPackage.eINSTANCE); + RegexPackageImpl theRegexPackage = (RegexPackageImpl)(EPackage.Registry.INSTANCE.getEPackage(RegexPackage.eNS_URI) instanceof RegexPackageImpl ? EPackage.Registry.INSTANCE.getEPackage(RegexPackage.eNS_URI) : RegexPackage.eINSTANCE); + PerfPackageImpl thePerfPackage = (PerfPackageImpl)(EPackage.Registry.INSTANCE.getEPackage(PerfPackage.eNS_URI) instanceof PerfPackageImpl ? EPackage.Registry.INSTANCE.getEPackage(PerfPackage.eNS_URI) : PerfPackage.eINSTANCE); + JavaPackageImpl theJavaPackage = (JavaPackageImpl)(EPackage.Registry.INSTANCE.getEPackage(JavaPackage.eNS_URI) instanceof JavaPackageImpl ? EPackage.Registry.INSTANCE.getEPackage(JavaPackage.eNS_URI) : JavaPackage.eINSTANCE); + CallGraphPackageImpl theCallGraphPackage = (CallGraphPackageImpl)(EPackage.Registry.INSTANCE.getEPackage(CallGraphPackage.eNS_URI) instanceof CallGraphPackageImpl ? EPackage.Registry.INSTANCE.getEPackage(CallGraphPackage.eNS_URI) : CallGraphPackage.eINSTANCE); + PointerAnalysisPackageImpl thePointerAnalysisPackage = (PointerAnalysisPackageImpl)(EPackage.Registry.INSTANCE.getEPackage(PointerAnalysisPackage.eNS_URI) instanceof PointerAnalysisPackageImpl ? EPackage.Registry.INSTANCE.getEPackage(PointerAnalysisPackage.eNS_URI) : PointerAnalysisPackage.eINSTANCE); + JavaScopePackageImpl theJavaScopePackage = (JavaScopePackageImpl)(EPackage.Registry.INSTANCE.getEPackage(JavaScopePackage.eNS_URI) instanceof JavaScopePackageImpl ? EPackage.Registry.INSTANCE.getEPackage(JavaScopePackage.eNS_URI) : JavaScopePackage.eINSTANCE); + J2EEScopePackageImpl theJ2EEScopePackage = (J2EEScopePackageImpl)(EPackage.Registry.INSTANCE.getEPackage(J2EEScopePackage.eNS_URI) instanceof J2EEScopePackageImpl ? EPackage.Registry.INSTANCE.getEPackage(J2EEScopePackage.eNS_URI) : J2EEScopePackage.eINSTANCE); + + // Create package meta-data objects + theCommonPackage.createPackageContents(); + theGraphPackage.createPackageContents(); + theRegexPackage.createPackageContents(); + thePerfPackage.createPackageContents(); + theJavaPackage.createPackageContents(); + theCallGraphPackage.createPackageContents(); + thePointerAnalysisPackage.createPackageContents(); + theJavaScopePackage.createPackageContents(); + theJ2EEScopePackage.createPackageContents(); + + // Initialize created meta-data + theCommonPackage.initializePackageContents(); + theGraphPackage.initializePackageContents(); + theRegexPackage.initializePackageContents(); + thePerfPackage.initializePackageContents(); + theJavaPackage.initializePackageContents(); + theCallGraphPackage.initializePackageContents(); + thePointerAnalysisPackage.initializePackageContents(); + theJavaScopePackage.initializePackageContents(); + theJ2EEScopePackage.initializePackageContents(); + + // Mark meta-data to indicate it can't be changed + theCommonPackage.freeze(); + + return theCommonPackage; + } + + /** + * + * + * @generated + */ + public EClass getECollection() { + return eCollectionEClass; + } + + /** + * + * + * @generated + */ + public EReference getECollection_Contents() { + return (EReference)eCollectionEClass.getEStructuralFeatures().get(0); + } + + /** + * + * + * @generated + */ + public EClass getEPair() { + return ePairEClass; + } + + /** + * + * + * @generated + */ + public EReference getEPair_X() { + return (EReference)ePairEClass.getEStructuralFeatures().get(0); + } + + /** + * + * + * @generated + */ + public EReference getEPair_Y() { + return (EReference)ePairEClass.getEStructuralFeatures().get(1); + } + + /** + * + * + * @generated + */ + public EClass getERelation() { + return eRelationEClass; + } + + /** + * + * + * @generated + */ + public EAttribute getERelation_Name() { + return (EAttribute)eRelationEClass.getEStructuralFeatures().get(0); + } + + /** + * + * + * @generated + */ + public EClass getEContainer() { + return eContainerEClass; + } + + /** + * + * + * @generated + */ + public EReference getEContainer_Containees() { + return (EReference)eContainerEClass.getEStructuralFeatures().get(0); + } + + /** + * + * + * @generated + */ + public EClass getENotContainer() { + return eNotContainerEClass; + } + + /** + * + * + * @generated + */ + public EReference getENotContainer_Elements() { + return (EReference)eNotContainerEClass.getEStructuralFeatures().get(0); + } + + /** + * + * + * @generated + */ + public EClass getEStringHolder() { + return eStringHolderEClass; + } + + /** + * + * + * @generated + */ + public EAttribute getEStringHolder_Value() { + return (EAttribute)eStringHolderEClass.getEStructuralFeatures().get(0); + } + + /** + * + * + * @generated + */ + public EClass getEObjectWithContainerId() { + return eObjectWithContainerIdEClass; + } + + /** + * + * + * @generated + */ + public EAttribute getEObjectWithContainerId_Id() { + return (EAttribute)eObjectWithContainerIdEClass.getEStructuralFeatures().get(0); + } + + /** + * + * + * @generated + */ + public EDataType getEJavaCollection() { + return eJavaCollectionEDataType; + } + + /** + * + * + * @generated + */ + public EDataType getEFile() { + return eFileEDataType; + } + + /** + * + * + * @generated + */ + public EDataType getEIterator() { + return eIteratorEDataType; + } + + /** + * + * + * @generated + */ + public CommonFactory getCommonFactory() { + return (CommonFactory)getEFactoryInstance(); + } + + /** + * + * + * @generated + */ + private boolean isCreated = false; + + /** + * Creates the meta-model objects for the package. This method is + * guarded to have no affect on any invocation but its first. + * + * + * @generated + */ + public void createPackageContents() { + if (isCreated) return; + isCreated = true; + + // Create classes and their features + eCollectionEClass = createEClass(ECOLLECTION); + createEReference(eCollectionEClass, ECOLLECTION__CONTENTS); + + ePairEClass = createEClass(EPAIR); + createEReference(ePairEClass, EPAIR__X); + createEReference(ePairEClass, EPAIR__Y); + + eRelationEClass = createEClass(ERELATION); + createEAttribute(eRelationEClass, ERELATION__NAME); + + eContainerEClass = createEClass(ECONTAINER); + createEReference(eContainerEClass, ECONTAINER__CONTAINEES); + + eNotContainerEClass = createEClass(ENOT_CONTAINER); + createEReference(eNotContainerEClass, ENOT_CONTAINER__ELEMENTS); + + eStringHolderEClass = createEClass(ESTRING_HOLDER); + createEAttribute(eStringHolderEClass, ESTRING_HOLDER__VALUE); + + eObjectWithContainerIdEClass = createEClass(EOBJECT_WITH_CONTAINER_ID); + createEAttribute(eObjectWithContainerIdEClass, EOBJECT_WITH_CONTAINER_ID__ID); + + // Create data types + eJavaCollectionEDataType = createEDataType(EJAVA_COLLECTION); + eFileEDataType = createEDataType(EFILE); + eIteratorEDataType = createEDataType(EITERATOR); + } + + /** + * + * + * @generated + */ + private boolean isInitialized = false; + + /** + * Complete the initialization of the package and its meta-model. This + * method is guarded to have no affect on any invocation but its first. + * + * + * @generated + */ + public void initializePackageContents() { + if (isInitialized) return; + isInitialized = true; + + // Initialize package + setName(eNAME); + setNsPrefix(eNS_PREFIX); + setNsURI(eNS_URI); + + // Add supertypes to classes + eRelationEClass.getESuperTypes().add(this.getEContainer()); + eContainerEClass.getESuperTypes().add(this.getECollection()); + eNotContainerEClass.getESuperTypes().add(this.getECollection()); + + // Initialize classes and features; add operations and parameters + initEClass(eCollectionEClass, ECollection.class, "ECollection", IS_ABSTRACT, IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); + initEReference(getECollection_Contents(), ecorePackage.getEObject(), null, "contents", null, 0, -1, ECollection.class, IS_TRANSIENT, IS_VOLATILE, IS_CHANGEABLE, !IS_COMPOSITE, IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); + + initEClass(ePairEClass, EPair.class, "EPair", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); + initEReference(getEPair_X(), ecorePackage.getEObject(), null, "X", null, 1, 1, EPair.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_COMPOSITE, IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); + initEReference(getEPair_Y(), ecorePackage.getEObject(), null, "Y", null, 1, 1, EPair.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_COMPOSITE, IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); + + initEClass(eRelationEClass, ERelation.class, "ERelation", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); + initEAttribute(getERelation_Name(), ecorePackage.getEString(), "name", null, 0, 1, ERelation.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); + + initEClass(eContainerEClass, EContainer.class, "EContainer", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); + initEReference(getEContainer_Containees(), ecorePackage.getEObject(), null, "containees", null, 0, -1, EContainer.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, IS_COMPOSITE, !IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); + + initEClass(eNotContainerEClass, ENotContainer.class, "ENotContainer", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); + initEReference(getENotContainer_Elements(), ecorePackage.getEObject(), null, "elements", null, 0, -1, ENotContainer.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_COMPOSITE, IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); + + initEClass(eStringHolderEClass, EStringHolder.class, "EStringHolder", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); + initEAttribute(getEStringHolder_Value(), ecorePackage.getEString(), "value", null, 1, 1, EStringHolder.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); + + initEClass(eObjectWithContainerIdEClass, EObjectWithContainerId.class, "EObjectWithContainerId", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); + initEAttribute(getEObjectWithContainerId_Id(), ecorePackage.getEInt(), "id", "-1", 1, 1, EObjectWithContainerId.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, IS_ID, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); + + // Initialize data types + initEDataType(eJavaCollectionEDataType, Collection.class, "EJavaCollection", !IS_SERIALIZABLE, !IS_GENERATED_INSTANCE_CLASS); + initEDataType(eFileEDataType, File.class, "EFile", !IS_SERIALIZABLE, !IS_GENERATED_INSTANCE_CLASS); + initEDataType(eIteratorEDataType, Iterator.class, "EIterator", !IS_SERIALIZABLE, !IS_GENERATED_INSTANCE_CLASS); + + // Create resource + createResource(eNS_URI); + } + +} //CommonPackageImpl diff --git a/com.ibm.wala.emf/src/com/ibm/wala/ecore/common/impl/EContainerImpl.java b/com.ibm.wala.emf/src/com/ibm/wala/ecore/common/impl/EContainerImpl.java new file mode 100644 index 000000000..6abfa4ff2 --- /dev/null +++ b/com.ibm.wala.emf/src/com/ibm/wala/ecore/common/impl/EContainerImpl.java @@ -0,0 +1,165 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.common.impl; + +import java.util.Collection; + +import org.eclipse.emf.common.notify.NotificationChain; +import org.eclipse.emf.common.util.EList; +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.InternalEObject; +import org.eclipse.emf.ecore.impl.EObjectImpl; +import org.eclipse.emf.ecore.util.EObjectContainmentEList; +import org.eclipse.emf.ecore.util.InternalEList; + +import com.ibm.wala.ecore.common.CommonPackage; +import com.ibm.wala.ecore.common.EContainer; + +/** + * + * An implementation of the model object 'EContainer'. + * + *

                              + * The following features are implemented: + *

                                + *
                              • {@link com.ibm.wala.ecore.common.impl.EContainerImpl#getContents Contents}
                              • + *
                              • {@link com.ibm.wala.ecore.common.impl.EContainerImpl#getContainees Containees}
                              • + *
                              + *

                              + * + * @generated + */ +public class EContainerImpl extends EObjectImpl implements EContainer { + /** + * The cached value of the '{@link #getContainees() Containees}' containment reference list. + * + * + * @see #getContainees() + * @generated + * @ordered + */ + protected EList containees = null; + + /** + * + * + * @generated + */ + protected EContainerImpl() { + super(); + } + + /** + * + * + * @generated + */ + protected EClass eStaticClass() { + return CommonPackage.Literals.ECONTAINER; + } + + /** + * + * + */ + public EList getContents() { + return getContainees(); + } + + /** + * + * + * @generated + */ + public EList getContainees() { + if (containees == null) { + containees = new EObjectContainmentEList(EObject.class, this, CommonPackage.ECONTAINER__CONTAINEES); + } + return containees; + } + + /** + * + * + * @generated + */ + public NotificationChain eInverseRemove(InternalEObject otherEnd, int featureID, NotificationChain msgs) { + switch (featureID) { + case CommonPackage.ECONTAINER__CONTAINEES: + return ((InternalEList)getContainees()).basicRemove(otherEnd, msgs); + } + return super.eInverseRemove(otherEnd, featureID, msgs); + } + + /** + * + * + * @generated + */ + public Object eGet(int featureID, boolean resolve, boolean coreType) { + switch (featureID) { + case CommonPackage.ECONTAINER__CONTENTS: + return getContents(); + case CommonPackage.ECONTAINER__CONTAINEES: + return getContainees(); + } + return super.eGet(featureID, resolve, coreType); + } + + /** + * + * + * @generated + */ + public void eSet(int featureID, Object newValue) { + switch (featureID) { + case CommonPackage.ECONTAINER__CONTENTS: + getContents().clear(); + getContents().addAll((Collection)newValue); + return; + case CommonPackage.ECONTAINER__CONTAINEES: + getContainees().clear(); + getContainees().addAll((Collection)newValue); + return; + } + super.eSet(featureID, newValue); + } + + /** + * + * + * @generated + */ + public void eUnset(int featureID) { + switch (featureID) { + case CommonPackage.ECONTAINER__CONTENTS: + getContents().clear(); + return; + case CommonPackage.ECONTAINER__CONTAINEES: + getContainees().clear(); + return; + } + super.eUnset(featureID); + } + + /** + * + * + * @generated + */ + public boolean eIsSet(int featureID) { + switch (featureID) { + case CommonPackage.ECONTAINER__CONTENTS: + return !getContents().isEmpty(); + case CommonPackage.ECONTAINER__CONTAINEES: + return containees != null && !containees.isEmpty(); + } + return super.eIsSet(featureID); + } + +} //EContainerImpl \ No newline at end of file diff --git a/com.ibm.wala.emf/src/com/ibm/wala/ecore/common/impl/ENotContainerImpl.java b/com.ibm.wala.emf/src/com/ibm/wala/ecore/common/impl/ENotContainerImpl.java new file mode 100644 index 000000000..c36c97ce5 --- /dev/null +++ b/com.ibm.wala.emf/src/com/ibm/wala/ecore/common/impl/ENotContainerImpl.java @@ -0,0 +1,150 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.common.impl; + +import com.ibm.wala.ecore.common.CommonPackage; +import com.ibm.wala.ecore.common.ENotContainer; + +import java.util.Collection; + +import org.eclipse.emf.common.util.EList; + +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EObject; + +import org.eclipse.emf.ecore.impl.EObjectImpl; + +import org.eclipse.emf.ecore.util.EObjectResolvingEList; + +/** + * + * An implementation of the model object 'ENot Container'. + * + *

                              + * The following features are implemented: + *

                                + *
                              • {@link com.ibm.wala.ecore.common.impl.ENotContainerImpl#getContents Contents}
                              • + *
                              • {@link com.ibm.wala.ecore.common.impl.ENotContainerImpl#getElements Elements}
                              • + *
                              + *

                              + * + * @generated + */ +public class ENotContainerImpl extends EObjectImpl implements ENotContainer { + /** + * The cached value of the '{@link #getElements() Elements}' reference list. + * + * + * @see #getElements() + * @generated + * @ordered + */ + protected EList elements = null; + + /** + * + * + * @generated + */ + protected ENotContainerImpl() { + super(); + } + + /** + * + * + * @generated + */ + protected EClass eStaticClass() { + return CommonPackage.Literals.ENOT_CONTAINER; + } + + /** + */ + public EList getContents() { + return getElements(); + } + + /** + * + * + * @generated + */ + public EList getElements() { + if (elements == null) { + elements = new EObjectResolvingEList(EObject.class, this, CommonPackage.ENOT_CONTAINER__ELEMENTS); + } + return elements; + } + + /** + * + * + * @generated + */ + public Object eGet(int featureID, boolean resolve, boolean coreType) { + switch (featureID) { + case CommonPackage.ENOT_CONTAINER__CONTENTS: + return getContents(); + case CommonPackage.ENOT_CONTAINER__ELEMENTS: + return getElements(); + } + return super.eGet(featureID, resolve, coreType); + } + + /** + * + * + * @generated + */ + public void eSet(int featureID, Object newValue) { + switch (featureID) { + case CommonPackage.ENOT_CONTAINER__CONTENTS: + getContents().clear(); + getContents().addAll((Collection)newValue); + return; + case CommonPackage.ENOT_CONTAINER__ELEMENTS: + getElements().clear(); + getElements().addAll((Collection)newValue); + return; + } + super.eSet(featureID, newValue); + } + + /** + * + * + * @generated + */ + public void eUnset(int featureID) { + switch (featureID) { + case CommonPackage.ENOT_CONTAINER__CONTENTS: + getContents().clear(); + return; + case CommonPackage.ENOT_CONTAINER__ELEMENTS: + getElements().clear(); + return; + } + super.eUnset(featureID); + } + + /** + * + * + * @generated + */ + public boolean eIsSet(int featureID) { + switch (featureID) { + case CommonPackage.ENOT_CONTAINER__CONTENTS: + return !getContents().isEmpty(); + case CommonPackage.ENOT_CONTAINER__ELEMENTS: + return elements != null && !elements.isEmpty(); + } + return super.eIsSet(featureID); + } + +} //ENotContainerImpl \ No newline at end of file diff --git a/com.ibm.wala.emf/src/com/ibm/wala/ecore/common/impl/EObjectWithContainerIdImpl.java b/com.ibm.wala.emf/src/com/ibm/wala/ecore/common/impl/EObjectWithContainerIdImpl.java new file mode 100644 index 000000000..45dd0db2d --- /dev/null +++ b/com.ibm.wala.emf/src/com/ibm/wala/ecore/common/impl/EObjectWithContainerIdImpl.java @@ -0,0 +1,161 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.common.impl; + +import com.ibm.wala.ecore.common.CommonPackage; +import com.ibm.wala.ecore.common.EObjectWithContainerId; + +import org.eclipse.emf.common.notify.Notification; + +import org.eclipse.emf.ecore.EClass; + +import org.eclipse.emf.ecore.impl.ENotificationImpl; +import org.eclipse.emf.ecore.impl.EObjectImpl; + +/** + * + * An implementation of the model object 'EObject With Container Id'. + * + *

                              + * The following features are implemented: + *

                                + *
                              • {@link com.ibm.wala.ecore.common.impl.EObjectWithContainerIdImpl#getId Id}
                              • + *
                              + *

                              + * + * @generated + */ +public class EObjectWithContainerIdImpl extends EObjectImpl implements EObjectWithContainerId { + /** + * The default value of the '{@link #getId() Id}' attribute. + * + * + * @see #getId() + * @generated + * @ordered + */ + protected static final int ID_EDEFAULT = -1; + + /** + * The cached value of the '{@link #getId() Id}' attribute. + * + * + * @see #getId() + * @generated + * @ordered + */ + protected int id = ID_EDEFAULT; + + /** + * + * + * @generated + */ + protected EObjectWithContainerIdImpl() { + super(); + } + + /** + * + * + * @generated + */ + protected EClass eStaticClass() { + return CommonPackage.Literals.EOBJECT_WITH_CONTAINER_ID; + } + + /** + * + * + * @generated + */ + public int getId() { + return id; + } + + /** + * + * + * @generated + */ + public void setId(int newId) { + int oldId = id; + id = newId; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, CommonPackage.EOBJECT_WITH_CONTAINER_ID__ID, oldId, id)); + } + + /** + * + * + * @generated + */ + public Object eGet(int featureID, boolean resolve, boolean coreType) { + switch (featureID) { + case CommonPackage.EOBJECT_WITH_CONTAINER_ID__ID: + return new Integer(getId()); + } + return super.eGet(featureID, resolve, coreType); + } + + /** + * + * + * @generated + */ + public void eSet(int featureID, Object newValue) { + switch (featureID) { + case CommonPackage.EOBJECT_WITH_CONTAINER_ID__ID: + setId(((Integer)newValue).intValue()); + return; + } + super.eSet(featureID, newValue); + } + + /** + * + * + * @generated + */ + public void eUnset(int featureID) { + switch (featureID) { + case CommonPackage.EOBJECT_WITH_CONTAINER_ID__ID: + setId(ID_EDEFAULT); + return; + } + super.eUnset(featureID); + } + + /** + * + * + * @generated + */ + public boolean eIsSet(int featureID) { + switch (featureID) { + case CommonPackage.EOBJECT_WITH_CONTAINER_ID__ID: + return id != ID_EDEFAULT; + } + return super.eIsSet(featureID); + } + + /** + * + * + * @generated + */ + public String toString() { + if (eIsProxy()) return super.toString(); + + StringBuffer result = new StringBuffer(super.toString()); + result.append(" (id: "); + result.append(id); + result.append(')'); + return result.toString(); + } + +} //EObjectWithContainerIdImpl \ No newline at end of file diff --git a/com.ibm.wala.emf/src/com/ibm/wala/ecore/common/impl/EPairImpl.java b/com.ibm.wala.emf/src/com/ibm/wala/ecore/common/impl/EPairImpl.java new file mode 100644 index 000000000..1c8113629 --- /dev/null +++ b/com.ibm.wala.emf/src/com/ibm/wala/ecore/common/impl/EPairImpl.java @@ -0,0 +1,216 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.common.impl; + +import com.ibm.wala.ecore.common.CommonPackage; +import com.ibm.wala.ecore.common.EPair; + +import org.eclipse.emf.common.notify.Notification; + +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.InternalEObject; + +import org.eclipse.emf.ecore.impl.ENotificationImpl; +import org.eclipse.emf.ecore.impl.EObjectImpl; + +/** + * + * An implementation of the model object 'EPair'. + * + *

                              + * The following features are implemented: + *

                                + *
                              • {@link com.ibm.wala.ecore.common.impl.EPairImpl#getX X}
                              • + *
                              • {@link com.ibm.wala.ecore.common.impl.EPairImpl#getY Y}
                              • + *
                              + *

                              + * + * @generated + */ +public class EPairImpl extends EObjectImpl implements EPair { + /** + * The cached value of the '{@link #getX() X}' reference. + * + * + * @see #getX() + * @generated + * @ordered + */ + protected EObject x = null; + + /** + * The cached value of the '{@link #getY() Y}' reference. + * + * + * @see #getY() + * @generated + * @ordered + */ + protected EObject y = null; + + /** + * + * + * @generated + */ + protected EPairImpl() { + super(); + } + + /** + * + * + * @generated + */ + protected EClass eStaticClass() { + return CommonPackage.Literals.EPAIR; + } + + /** + * + * + * @generated + */ + public EObject getX() { + if (x != null && x.eIsProxy()) { + InternalEObject oldX = (InternalEObject)x; + x = eResolveProxy(oldX); + if (x != oldX) { + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.RESOLVE, CommonPackage.EPAIR__X, oldX, x)); + } + } + return x; + } + + /** + * + * + * @generated + */ + public EObject basicGetX() { + return x; + } + + /** + * + * + * @generated + */ + public void setX(EObject newX) { + EObject oldX = x; + x = newX; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, CommonPackage.EPAIR__X, oldX, x)); + } + + /** + * + * + * @generated + */ + public EObject getY() { + if (y != null && y.eIsProxy()) { + InternalEObject oldY = (InternalEObject)y; + y = eResolveProxy(oldY); + if (y != oldY) { + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.RESOLVE, CommonPackage.EPAIR__Y, oldY, y)); + } + } + return y; + } + + /** + * + * + * @generated + */ + public EObject basicGetY() { + return y; + } + + /** + * + * + * @generated + */ + public void setY(EObject newY) { + EObject oldY = y; + y = newY; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, CommonPackage.EPAIR__Y, oldY, y)); + } + + /** + * + * + * @generated + */ + public Object eGet(int featureID, boolean resolve, boolean coreType) { + switch (featureID) { + case CommonPackage.EPAIR__X: + if (resolve) return getX(); + return basicGetX(); + case CommonPackage.EPAIR__Y: + if (resolve) return getY(); + return basicGetY(); + } + return super.eGet(featureID, resolve, coreType); + } + + /** + * + * + * @generated + */ + public void eSet(int featureID, Object newValue) { + switch (featureID) { + case CommonPackage.EPAIR__X: + setX((EObject)newValue); + return; + case CommonPackage.EPAIR__Y: + setY((EObject)newValue); + return; + } + super.eSet(featureID, newValue); + } + + /** + * + * + * @generated + */ + public void eUnset(int featureID) { + switch (featureID) { + case CommonPackage.EPAIR__X: + setX((EObject)null); + return; + case CommonPackage.EPAIR__Y: + setY((EObject)null); + return; + } + super.eUnset(featureID); + } + + /** + * + * + * @generated + */ + public boolean eIsSet(int featureID) { + switch (featureID) { + case CommonPackage.EPAIR__X: + return x != null; + case CommonPackage.EPAIR__Y: + return y != null; + } + return super.eIsSet(featureID); + } + +} //EPairImpl \ No newline at end of file diff --git a/com.ibm.wala.emf/src/com/ibm/wala/ecore/common/impl/ERelationImpl.java b/com.ibm.wala.emf/src/com/ibm/wala/ecore/common/impl/ERelationImpl.java new file mode 100644 index 000000000..40ffa3b6d --- /dev/null +++ b/com.ibm.wala.emf/src/com/ibm/wala/ecore/common/impl/ERelationImpl.java @@ -0,0 +1,160 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.common.impl; + +import com.ibm.wala.ecore.common.CommonPackage; +import com.ibm.wala.ecore.common.ERelation; + +import org.eclipse.emf.common.notify.Notification; + +import org.eclipse.emf.ecore.EClass; + +import org.eclipse.emf.ecore.impl.ENotificationImpl; + +/** + * + * An implementation of the model object 'ERelation'. + * + *

                              + * The following features are implemented: + *

                                + *
                              • {@link com.ibm.wala.ecore.common.impl.ERelationImpl#getName Name}
                              • + *
                              + *

                              + * + * @generated + */ +public class ERelationImpl extends EContainerImpl implements ERelation { + /** + * The default value of the '{@link #getName() Name}' attribute. + * + * + * @see #getName() + * @generated + * @ordered + */ + protected static final String NAME_EDEFAULT = null; + + /** + * The cached value of the '{@link #getName() Name}' attribute. + * + * + * @see #getName() + * @generated + * @ordered + */ + protected String name = NAME_EDEFAULT; + + /** + * + * + * @generated + */ + protected ERelationImpl() { + super(); + } + + /** + * + * + * @generated + */ + protected EClass eStaticClass() { + return CommonPackage.Literals.ERELATION; + } + + /** + * + * + * @generated + */ + public String getName() { + return name; + } + + /** + * + * + * @generated + */ + public void setName(String newName) { + String oldName = name; + name = newName; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, CommonPackage.ERELATION__NAME, oldName, name)); + } + + /** + * + * + * @generated + */ + public Object eGet(int featureID, boolean resolve, boolean coreType) { + switch (featureID) { + case CommonPackage.ERELATION__NAME: + return getName(); + } + return super.eGet(featureID, resolve, coreType); + } + + /** + * + * + * @generated + */ + public void eSet(int featureID, Object newValue) { + switch (featureID) { + case CommonPackage.ERELATION__NAME: + setName((String)newValue); + return; + } + super.eSet(featureID, newValue); + } + + /** + * + * + * @generated + */ + public void eUnset(int featureID) { + switch (featureID) { + case CommonPackage.ERELATION__NAME: + setName(NAME_EDEFAULT); + return; + } + super.eUnset(featureID); + } + + /** + * + * + * @generated + */ + public boolean eIsSet(int featureID) { + switch (featureID) { + case CommonPackage.ERELATION__NAME: + return NAME_EDEFAULT == null ? name != null : !NAME_EDEFAULT.equals(name); + } + return super.eIsSet(featureID); + } + + /** + * + * + * @generated + */ + public String toString() { + if (eIsProxy()) return super.toString(); + + StringBuffer result = new StringBuffer(super.toString()); + result.append(" (name: "); + result.append(name); + result.append(')'); + return result.toString(); + } + +} //ERelationImpl \ No newline at end of file diff --git a/com.ibm.wala.emf/src/com/ibm/wala/ecore/common/impl/EStringHolderImpl.java b/com.ibm.wala.emf/src/com/ibm/wala/ecore/common/impl/EStringHolderImpl.java new file mode 100644 index 000000000..ca900857e --- /dev/null +++ b/com.ibm.wala.emf/src/com/ibm/wala/ecore/common/impl/EStringHolderImpl.java @@ -0,0 +1,161 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.common.impl; + +import com.ibm.wala.ecore.common.CommonPackage; +import com.ibm.wala.ecore.common.EStringHolder; + +import org.eclipse.emf.common.notify.Notification; + +import org.eclipse.emf.ecore.EClass; + +import org.eclipse.emf.ecore.impl.ENotificationImpl; +import org.eclipse.emf.ecore.impl.EObjectImpl; + +/** + * + * An implementation of the model object 'EString Holder'. + * + *

                              + * The following features are implemented: + *

                                + *
                              • {@link com.ibm.wala.ecore.common.impl.EStringHolderImpl#getValue Value}
                              • + *
                              + *

                              + * + * @generated + */ +public class EStringHolderImpl extends EObjectImpl implements EStringHolder { + /** + * The default value of the '{@link #getValue() Value}' attribute. + * + * + * @see #getValue() + * @generated + * @ordered + */ + protected static final String VALUE_EDEFAULT = null; + + /** + * The cached value of the '{@link #getValue() Value}' attribute. + * + * + * @see #getValue() + * @generated + * @ordered + */ + protected String value = VALUE_EDEFAULT; + + /** + * + * + * @generated + */ + protected EStringHolderImpl() { + super(); + } + + /** + * + * + * @generated + */ + protected EClass eStaticClass() { + return CommonPackage.Literals.ESTRING_HOLDER; + } + + /** + * + * + * @generated + */ + public String getValue() { + return value; + } + + /** + * + * + * @generated + */ + public void setValue(String newValue) { + String oldValue = value; + value = newValue; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, CommonPackage.ESTRING_HOLDER__VALUE, oldValue, value)); + } + + /** + * + * + * @generated + */ + public Object eGet(int featureID, boolean resolve, boolean coreType) { + switch (featureID) { + case CommonPackage.ESTRING_HOLDER__VALUE: + return getValue(); + } + return super.eGet(featureID, resolve, coreType); + } + + /** + * + * + * @generated + */ + public void eSet(int featureID, Object newValue) { + switch (featureID) { + case CommonPackage.ESTRING_HOLDER__VALUE: + setValue((String)newValue); + return; + } + super.eSet(featureID, newValue); + } + + /** + * + * + * @generated + */ + public void eUnset(int featureID) { + switch (featureID) { + case CommonPackage.ESTRING_HOLDER__VALUE: + setValue(VALUE_EDEFAULT); + return; + } + super.eUnset(featureID); + } + + /** + * + * + * @generated + */ + public boolean eIsSet(int featureID) { + switch (featureID) { + case CommonPackage.ESTRING_HOLDER__VALUE: + return VALUE_EDEFAULT == null ? value != null : !VALUE_EDEFAULT.equals(value); + } + return super.eIsSet(featureID); + } + + /** + * + * + * @generated + */ + public String toString() { + if (eIsProxy()) return super.toString(); + + StringBuffer result = new StringBuffer(super.toString()); + result.append(" (value: "); + result.append(value); + result.append(')'); + return result.toString(); + } + +} //EStringHolderImpl \ No newline at end of file diff --git a/com.ibm.wala.emf/src/com/ibm/wala/ecore/common/util/CommonAdapterFactory.java b/com.ibm.wala.emf/src/com/ibm/wala/ecore/common/util/CommonAdapterFactory.java new file mode 100644 index 000000000..a9ac7b5d7 --- /dev/null +++ b/com.ibm.wala.emf/src/com/ibm/wala/ecore/common/util/CommonAdapterFactory.java @@ -0,0 +1,222 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.common.util; + +import com.ibm.wala.ecore.common.*; + +import org.eclipse.emf.common.notify.Adapter; +import org.eclipse.emf.common.notify.Notifier; + +import org.eclipse.emf.common.notify.impl.AdapterFactoryImpl; + +import org.eclipse.emf.ecore.EObject; + +/** + * + * The Adapter Factory for the model. + * It provides an adapter createXXX method for each class of the model. + * + * @see com.ibm.wala.ecore.common.CommonPackage + * @generated + */ +public class CommonAdapterFactory extends AdapterFactoryImpl { + /** + * The cached model package. + * + * + * @generated + */ + protected static CommonPackage modelPackage; + + /** + * Creates an instance of the adapter factory. + * + * + * @generated + */ + public CommonAdapterFactory() { + if (modelPackage == null) { + modelPackage = CommonPackage.eINSTANCE; + } + } + + /** + * Returns whether this factory is applicable for the type of the object. + * + * This implementation returns true if the object is either the model's package or is an instance object of the model. + * + * @return whether this factory is applicable for the type of the object. + * @generated + */ + public boolean isFactoryForType(Object object) { + if (object == modelPackage) { + return true; + } + if (object instanceof EObject) { + return ((EObject)object).eClass().getEPackage() == modelPackage; + } + return false; + } + + /** + * The switch the delegates to the createXXX methods. + * + * + * @generated + */ + protected CommonSwitch modelSwitch = + new CommonSwitch() { + public Object caseECollection(ECollection object) { + return createECollectionAdapter(); + } + public Object caseEPair(EPair object) { + return createEPairAdapter(); + } + public Object caseERelation(ERelation object) { + return createERelationAdapter(); + } + public Object caseEContainer(EContainer object) { + return createEContainerAdapter(); + } + public Object caseENotContainer(ENotContainer object) { + return createENotContainerAdapter(); + } + public Object caseEStringHolder(EStringHolder object) { + return createEStringHolderAdapter(); + } + public Object caseEObjectWithContainerId(EObjectWithContainerId object) { + return createEObjectWithContainerIdAdapter(); + } + public Object defaultCase(EObject object) { + return createEObjectAdapter(); + } + }; + + /** + * Creates an adapter for the target. + * + * + * @param target the object to adapt. + * @return the adapter for the target. + * @generated + */ + public Adapter createAdapter(Notifier target) { + return (Adapter)modelSwitch.doSwitch((EObject)target); + } + + + /** + * Creates a new adapter for an object of class '{@link com.ibm.wala.ecore.common.ECollection ECollection}'. + * + * This default implementation returns null so that we can easily ignore cases; + * it's useful to ignore a case when inheritance will catch all the cases anyway. + * + * @return the new adapter. + * @see com.ibm.wala.ecore.common.ECollection + * @generated + */ + public Adapter createECollectionAdapter() { + return null; + } + + /** + * Creates a new adapter for an object of class '{@link com.ibm.wala.ecore.common.EPair EPair}'. + * + * This default implementation returns null so that we can easily ignore cases; + * it's useful to ignore a case when inheritance will catch all the cases anyway. + * + * @return the new adapter. + * @see com.ibm.wala.ecore.common.EPair + * @generated + */ + public Adapter createEPairAdapter() { + return null; + } + + /** + * Creates a new adapter for an object of class '{@link com.ibm.wala.ecore.common.ERelation ERelation}'. + * + * This default implementation returns null so that we can easily ignore cases; + * it's useful to ignore a case when inheritance will catch all the cases anyway. + * + * @return the new adapter. + * @see com.ibm.wala.ecore.common.ERelation + * @generated + */ + public Adapter createERelationAdapter() { + return null; + } + + /** + * Creates a new adapter for an object of class '{@link com.ibm.wala.ecore.common.EContainer EContainer}'. + * + * This default implementation returns null so that we can easily ignore cases; + * it's useful to ignore a case when inheritance will catch all the cases anyway. + * + * @return the new adapter. + * @see com.ibm.wala.ecore.common.EContainer + * @generated + */ + public Adapter createEContainerAdapter() { + return null; + } + + /** + * Creates a new adapter for an object of class '{@link com.ibm.wala.ecore.common.ENotContainer ENot Container}'. + * + * This default implementation returns null so that we can easily ignore cases; + * it's useful to ignore a case when inheritance will catch all the cases anyway. + * + * @return the new adapter. + * @see com.ibm.wala.ecore.common.ENotContainer + * @generated + */ + public Adapter createENotContainerAdapter() { + return null; + } + + /** + * Creates a new adapter for an object of class '{@link com.ibm.wala.ecore.common.EStringHolder EString Holder}'. + * + * This default implementation returns null so that we can easily ignore cases; + * it's useful to ignore a case when inheritance will catch all the cases anyway. + * + * @return the new adapter. + * @see com.ibm.wala.ecore.common.EStringHolder + * @generated + */ + public Adapter createEStringHolderAdapter() { + return null; + } + + /** + * Creates a new adapter for an object of class '{@link com.ibm.wala.ecore.common.EObjectWithContainerId EObject With Container Id}'. + * + * This default implementation returns null so that we can easily ignore cases; + * it's useful to ignore a case when inheritance will catch all the cases anyway. + * + * @return the new adapter. + * @see com.ibm.wala.ecore.common.EObjectWithContainerId + * @generated + */ + public Adapter createEObjectWithContainerIdAdapter() { + return null; + } + + /** + * Creates a new adapter for the default case. + * + * This default implementation returns null. + * + * @return the new adapter. + * @generated + */ + public Adapter createEObjectAdapter() { + return null; + } + +} //CommonAdapterFactory diff --git a/com.ibm.wala.emf/src/com/ibm/wala/ecore/common/util/CommonSwitch.java b/com.ibm.wala.emf/src/com/ibm/wala/ecore/common/util/CommonSwitch.java new file mode 100644 index 000000000..6af576926 --- /dev/null +++ b/com.ibm.wala.emf/src/com/ibm/wala/ecore/common/util/CommonSwitch.java @@ -0,0 +1,260 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.common.util; + +import com.ibm.wala.ecore.common.*; + +import java.util.List; + +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EObject; + +/** + * + * The Switch for the model's inheritance hierarchy. + * It supports the call {@link #doSwitch(EObject) doSwitch(object)} + * to invoke the caseXXX method for each class of the model, + * starting with the actual class of the object + * and proceeding up the inheritance hierarchy + * until a non-null result is returned, + * which is the result of the switch. + * + * @see com.ibm.wala.ecore.common.CommonPackage + * @generated + */ +public class CommonSwitch { + /** + * The cached model package + * + * + * @generated + */ + protected static CommonPackage modelPackage; + + /** + * Creates an instance of the switch. + * + * + * @generated + */ + public CommonSwitch() { + if (modelPackage == null) { + modelPackage = CommonPackage.eINSTANCE; + } + } + + /** + * Calls caseXXX for each class of the model until one returns a non null result; it yields that result. + * + * + * @return the first non-null result returned by a caseXXX call. + * @generated + */ + public Object doSwitch(EObject theEObject) { + return doSwitch(theEObject.eClass(), theEObject); + } + + /** + * Calls caseXXX for each class of the model until one returns a non null result; it yields that result. + * + * + * @return the first non-null result returned by a caseXXX call. + * @generated + */ + protected Object doSwitch(EClass theEClass, EObject theEObject) { + if (theEClass.eContainer() == modelPackage) { + return doSwitch(theEClass.getClassifierID(), theEObject); + } + else { + List eSuperTypes = theEClass.getESuperTypes(); + return + eSuperTypes.isEmpty() ? + defaultCase(theEObject) : + doSwitch((EClass)eSuperTypes.get(0), theEObject); + } + } + + /** + * Calls caseXXX for each class of the model until one returns a non null result; it yields that result. + * + * + * @return the first non-null result returned by a caseXXX call. + * @generated + */ + protected Object doSwitch(int classifierID, EObject theEObject) { + switch (classifierID) { + case CommonPackage.ECOLLECTION: { + ECollection eCollection = (ECollection)theEObject; + Object result = caseECollection(eCollection); + if (result == null) result = defaultCase(theEObject); + return result; + } + case CommonPackage.EPAIR: { + EPair ePair = (EPair)theEObject; + Object result = caseEPair(ePair); + if (result == null) result = defaultCase(theEObject); + return result; + } + case CommonPackage.ERELATION: { + ERelation eRelation = (ERelation)theEObject; + Object result = caseERelation(eRelation); + if (result == null) result = caseEContainer(eRelation); + if (result == null) result = caseECollection(eRelation); + if (result == null) result = defaultCase(theEObject); + return result; + } + case CommonPackage.ECONTAINER: { + EContainer eContainer = (EContainer)theEObject; + Object result = caseEContainer(eContainer); + if (result == null) result = caseECollection(eContainer); + if (result == null) result = defaultCase(theEObject); + return result; + } + case CommonPackage.ENOT_CONTAINER: { + ENotContainer eNotContainer = (ENotContainer)theEObject; + Object result = caseENotContainer(eNotContainer); + if (result == null) result = caseECollection(eNotContainer); + if (result == null) result = defaultCase(theEObject); + return result; + } + case CommonPackage.ESTRING_HOLDER: { + EStringHolder eStringHolder = (EStringHolder)theEObject; + Object result = caseEStringHolder(eStringHolder); + if (result == null) result = defaultCase(theEObject); + return result; + } + case CommonPackage.EOBJECT_WITH_CONTAINER_ID: { + EObjectWithContainerId eObjectWithContainerId = (EObjectWithContainerId)theEObject; + Object result = caseEObjectWithContainerId(eObjectWithContainerId); + if (result == null) result = defaultCase(theEObject); + return result; + } + default: return defaultCase(theEObject); + } + } + + /** + * Returns the result of interpretting the object as an instance of 'ECollection'. + * + * This implementation returns null; + * returning a non-null result will terminate the switch. + * + * @param object the target of the switch. + * @return the result of interpretting the object as an instance of 'ECollection'. + * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject) + * @generated + */ + public Object caseECollection(ECollection object) { + return null; + } + + /** + * Returns the result of interpretting the object as an instance of 'EPair'. + * + * This implementation returns null; + * returning a non-null result will terminate the switch. + * + * @param object the target of the switch. + * @return the result of interpretting the object as an instance of 'EPair'. + * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject) + * @generated + */ + public Object caseEPair(EPair object) { + return null; + } + + /** + * Returns the result of interpretting the object as an instance of 'ERelation'. + * + * This implementation returns null; + * returning a non-null result will terminate the switch. + * + * @param object the target of the switch. + * @return the result of interpretting the object as an instance of 'ERelation'. + * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject) + * @generated + */ + public Object caseERelation(ERelation object) { + return null; + } + + /** + * Returns the result of interpretting the object as an instance of 'EContainer'. + * + * This implementation returns null; + * returning a non-null result will terminate the switch. + * + * @param object the target of the switch. + * @return the result of interpretting the object as an instance of 'EContainer'. + * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject) + * @generated + */ + public Object caseEContainer(EContainer object) { + return null; + } + + /** + * Returns the result of interpretting the object as an instance of 'ENot Container'. + * + * This implementation returns null; + * returning a non-null result will terminate the switch. + * + * @param object the target of the switch. + * @return the result of interpretting the object as an instance of 'ENot Container'. + * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject) + * @generated + */ + public Object caseENotContainer(ENotContainer object) { + return null; + } + + /** + * Returns the result of interpretting the object as an instance of 'EString Holder'. + * + * This implementation returns null; + * returning a non-null result will terminate the switch. + * + * @param object the target of the switch. + * @return the result of interpretting the object as an instance of 'EString Holder'. + * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject) + * @generated + */ + public Object caseEStringHolder(EStringHolder object) { + return null; + } + + /** + * Returns the result of interpretting the object as an instance of 'EObject With Container Id'. + * + * This implementation returns null; + * returning a non-null result will terminate the switch. + * + * @param object the target of the switch. + * @return the result of interpretting the object as an instance of 'EObject With Container Id'. + * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject) + * @generated + */ + public Object caseEObjectWithContainerId(EObjectWithContainerId object) { + return null; + } + + /** + * Returns the result of interpretting the object as an instance of 'EObject'. + * + * This implementation returns null; + * returning a non-null result will terminate the switch, but this is the last case anyway. + * + * @param object the target of the switch. + * @return the result of interpretting the object as an instance of 'EObject'. + * @see #doSwitch(org.eclipse.emf.ecore.EObject) + * @generated + */ + public Object defaultCase(EObject object) { + return null; + } + +} //CommonSwitch diff --git a/com.ibm.wala.emf/src/com/ibm/wala/ecore/graph/EGraph.java b/com.ibm.wala.emf/src/com/ibm/wala/ecore/graph/EGraph.java new file mode 100644 index 000000000..4ace2b637 --- /dev/null +++ b/com.ibm.wala.emf/src/com/ibm/wala/ecore/graph/EGraph.java @@ -0,0 +1,84 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.graph; + +import com.ibm.wala.ecore.common.ECollection; +import com.ibm.wala.ecore.common.ERelation; + +import org.eclipse.emf.ecore.EObject; + +/** + * + * A representation of the model object 'EGraph'. + * + * + *

                              + * The following features are supported: + *

                                + *
                              • {@link com.ibm.wala.ecore.graph.EGraph#getNodes Nodes}
                              • + *
                              • {@link com.ibm.wala.ecore.graph.EGraph#getEdges Edges}
                              • + *
                              + *

                              + * + * @see com.ibm.wala.ecore.graph.GraphPackage#getEGraph() + * @model + * @generated + */ +public interface EGraph extends EObject { + /** + * Returns the value of the 'Nodes' reference. + * + *

                              + * If the meaning of the 'Nodes' reference isn't clear, + * there really should be more of a description here... + *

                              + * + * @return the value of the 'Nodes' reference. + * @see #setNodes(ECollection) + * @see com.ibm.wala.ecore.graph.GraphPackage#getEGraph_Nodes() + * @model required="true" + * @generated + */ + ECollection getNodes(); + + /** + * Sets the value of the '{@link com.ibm.wala.ecore.graph.EGraph#getNodes Nodes}' reference. + * + * + * @param value the new value of the 'Nodes' reference. + * @see #getNodes() + * @generated + */ + void setNodes(ECollection value); + + /** + * Returns the value of the 'Edges' containment reference. + * + *

                              + * If the meaning of the 'Edges' containment reference isn't clear, + * there really should be more of a description here... + *

                              + * + * @return the value of the 'Edges' containment reference. + * @see #setEdges(ERelation) + * @see com.ibm.wala.ecore.graph.GraphPackage#getEGraph_Edges() + * @model containment="true" required="true" + * @generated + */ + ERelation getEdges(); + + /** + * Sets the value of the '{@link com.ibm.wala.ecore.graph.EGraph#getEdges Edges}' containment reference. + * + * + * @param value the new value of the 'Edges' containment reference. + * @see #getEdges() + * @generated + */ + void setEdges(ERelation value); + +} // EGraph \ No newline at end of file diff --git a/com.ibm.wala.emf/src/com/ibm/wala/ecore/graph/ETree.java b/com.ibm.wala.emf/src/com/ibm/wala/ecore/graph/ETree.java new file mode 100644 index 000000000..a2f475098 --- /dev/null +++ b/com.ibm.wala.emf/src/com/ibm/wala/ecore/graph/ETree.java @@ -0,0 +1,21 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.graph; + + +/** + * + * A representation of the model object 'ETree'. + * + * + * + * @see com.ibm.wala.ecore.graph.GraphPackage#getETree() + * @model + * @generated + */ +public interface ETree extends EGraph { +} // ETree \ No newline at end of file diff --git a/com.ibm.wala.emf/src/com/ibm/wala/ecore/graph/GraphFactory.java b/com.ibm.wala.emf/src/com/ibm/wala/ecore/graph/GraphFactory.java new file mode 100644 index 000000000..90b42e92d --- /dev/null +++ b/com.ibm.wala.emf/src/com/ibm/wala/ecore/graph/GraphFactory.java @@ -0,0 +1,55 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.graph; + +import org.eclipse.emf.ecore.EFactory; + +/** + * + * The Factory for the model. + * It provides a create method for each non-abstract class of the model. + * + * @see com.ibm.wala.ecore.graph.GraphPackage + * @generated + */ +public interface GraphFactory extends EFactory { + /** + * The singleton instance of the factory. + * + * + * @generated + */ + GraphFactory eINSTANCE = com.ibm.wala.ecore.graph.impl.GraphFactoryImpl.init(); + + /** + * Returns a new object of class 'EGraph'. + * + * + * @return a new object of class 'EGraph'. + * @generated + */ + EGraph createEGraph(); + + /** + * Returns a new object of class 'ETree'. + * + * + * @return a new object of class 'ETree'. + * @generated + */ + ETree createETree(); + + /** + * Returns the package supported by this factory. + * + * + * @return the package supported by this factory. + * @generated + */ + GraphPackage getGraphPackage(); + +} //GraphFactory diff --git a/com.ibm.wala.emf/src/com/ibm/wala/ecore/graph/GraphPackage.java b/com.ibm.wala.emf/src/com/ibm/wala/ecore/graph/GraphPackage.java new file mode 100644 index 000000000..a12bb5aa5 --- /dev/null +++ b/com.ibm.wala.emf/src/com/ibm/wala/ecore/graph/GraphPackage.java @@ -0,0 +1,238 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.graph; + +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EPackage; +import org.eclipse.emf.ecore.EReference; + +/** + * + * The Package for the model. + * It contains accessors for the meta objects to represent + *
                                + *
                              • each class,
                              • + *
                              • each feature of each class,
                              • + *
                              • each enum,
                              • + *
                              • and each data type
                              • + *
                              + * + * @see com.ibm.wala.ecore.graph.GraphFactory + * @model kind="package" + * @generated + */ +public interface GraphPackage extends EPackage { + /** + * The package name. + * + * + * @generated + */ + String eNAME = "graph"; + + /** + * The package namespace URI. + * + * + * @generated + */ + String eNS_URI = "http:///com/ibm/wala/wala.ecore.graph"; + + /** + * The package namespace name. + * + * + * @generated + */ + String eNS_PREFIX = "com.ibm.wala.graph"; + + /** + * The singleton instance of the package. + * + * + * @generated + */ + GraphPackage eINSTANCE = com.ibm.wala.ecore.graph.impl.GraphPackageImpl.init(); + + /** + * The meta object id for the '{@link com.ibm.wala.ecore.graph.impl.EGraphImpl EGraph}' class. + * + * + * @see com.ibm.wala.ecore.graph.impl.EGraphImpl + * @see com.ibm.wala.ecore.graph.impl.GraphPackageImpl#getEGraph() + * @generated + */ + int EGRAPH = 0; + + /** + * The feature id for the 'Nodes' reference. + * + * + * @generated + * @ordered + */ + int EGRAPH__NODES = 0; + + /** + * The feature id for the 'Edges' containment reference. + * + * + * @generated + * @ordered + */ + int EGRAPH__EDGES = 1; + + /** + * The number of structural features of the 'EGraph' class. + * + * + * @generated + * @ordered + */ + int EGRAPH_FEATURE_COUNT = 2; + + /** + * The meta object id for the '{@link com.ibm.wala.ecore.graph.impl.ETreeImpl ETree}' class. + * + * + * @see com.ibm.wala.ecore.graph.impl.ETreeImpl + * @see com.ibm.wala.ecore.graph.impl.GraphPackageImpl#getETree() + * @generated + */ + int ETREE = 1; + + /** + * The feature id for the 'Nodes' reference. + * + * + * @generated + * @ordered + */ + int ETREE__NODES = EGRAPH__NODES; + + /** + * The feature id for the 'Edges' containment reference. + * + * + * @generated + * @ordered + */ + int ETREE__EDGES = EGRAPH__EDGES; + + /** + * The number of structural features of the 'ETree' class. + * + * + * @generated + * @ordered + */ + int ETREE_FEATURE_COUNT = EGRAPH_FEATURE_COUNT + 0; + + + /** + * Returns the meta object for class '{@link com.ibm.wala.ecore.graph.EGraph EGraph}'. + * + * + * @return the meta object for class 'EGraph'. + * @see com.ibm.wala.ecore.graph.EGraph + * @generated + */ + EClass getEGraph(); + + /** + * Returns the meta object for the reference '{@link com.ibm.wala.ecore.graph.EGraph#getNodes Nodes}'. + * + * + * @return the meta object for the reference 'Nodes'. + * @see com.ibm.wala.ecore.graph.EGraph#getNodes() + * @see #getEGraph() + * @generated + */ + EReference getEGraph_Nodes(); + + /** + * Returns the meta object for the containment reference '{@link com.ibm.wala.ecore.graph.EGraph#getEdges Edges}'. + * + * + * @return the meta object for the containment reference 'Edges'. + * @see com.ibm.wala.ecore.graph.EGraph#getEdges() + * @see #getEGraph() + * @generated + */ + EReference getEGraph_Edges(); + + /** + * Returns the meta object for class '{@link com.ibm.wala.ecore.graph.ETree ETree}'. + * + * + * @return the meta object for class 'ETree'. + * @see com.ibm.wala.ecore.graph.ETree + * @generated + */ + EClass getETree(); + + /** + * Returns the factory that creates the instances of the model. + * + * + * @return the factory that creates the instances of the model. + * @generated + */ + GraphFactory getGraphFactory(); + + /** + * + * Defines literals for the meta objects that represent + *
                                + *
                              • each class,
                              • + *
                              • each feature of each class,
                              • + *
                              • each enum,
                              • + *
                              • and each data type
                              • + *
                              + * + * @generated + */ + interface Literals { + /** + * The meta object literal for the '{@link com.ibm.wala.ecore.graph.impl.EGraphImpl EGraph}' class. + * + * + * @see com.ibm.wala.ecore.graph.impl.EGraphImpl + * @see com.ibm.wala.ecore.graph.impl.GraphPackageImpl#getEGraph() + * @generated + */ + EClass EGRAPH = eINSTANCE.getEGraph(); + + /** + * The meta object literal for the 'Nodes' reference feature. + * + * + * @generated + */ + EReference EGRAPH__NODES = eINSTANCE.getEGraph_Nodes(); + + /** + * The meta object literal for the 'Edges' containment reference feature. + * + * + * @generated + */ + EReference EGRAPH__EDGES = eINSTANCE.getEGraph_Edges(); + + /** + * The meta object literal for the '{@link com.ibm.wala.ecore.graph.impl.ETreeImpl ETree}' class. + * + * + * @see com.ibm.wala.ecore.graph.impl.ETreeImpl + * @see com.ibm.wala.ecore.graph.impl.GraphPackageImpl#getETree() + * @generated + */ + EClass ETREE = eINSTANCE.getETree(); + + } + +} //GraphPackage diff --git a/com.ibm.wala.emf/src/com/ibm/wala/ecore/graph/impl/EGraphImpl.java b/com.ibm.wala.emf/src/com/ibm/wala/ecore/graph/impl/EGraphImpl.java new file mode 100644 index 000000000..17d2d3c24 --- /dev/null +++ b/com.ibm.wala.emf/src/com/ibm/wala/ecore/graph/impl/EGraphImpl.java @@ -0,0 +1,236 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.graph.impl; + +import com.ibm.wala.ecore.common.ECollection; +import com.ibm.wala.ecore.common.ERelation; + +import com.ibm.wala.ecore.graph.EGraph; +import com.ibm.wala.ecore.graph.GraphPackage; + +import org.eclipse.emf.common.notify.Notification; +import org.eclipse.emf.common.notify.NotificationChain; + +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.InternalEObject; + +import org.eclipse.emf.ecore.impl.ENotificationImpl; +import org.eclipse.emf.ecore.impl.EObjectImpl; + +/** + * + * An implementation of the model object 'EGraph'. + * + *

                              + * The following features are implemented: + *

                                + *
                              • {@link com.ibm.wala.ecore.graph.impl.EGraphImpl#getNodes Nodes}
                              • + *
                              • {@link com.ibm.wala.ecore.graph.impl.EGraphImpl#getEdges Edges}
                              • + *
                              + *

                              + * + * @generated + */ +public class EGraphImpl extends EObjectImpl implements EGraph { + /** + * The cached value of the '{@link #getNodes() Nodes}' reference. + * + * + * @see #getNodes() + * @generated + * @ordered + */ + protected ECollection nodes = null; + + /** + * The cached value of the '{@link #getEdges() Edges}' containment reference. + * + * + * @see #getEdges() + * @generated + * @ordered + */ + protected ERelation edges = null; + + /** + * + * + * @generated + */ + protected EGraphImpl() { + super(); + } + + /** + * + * + * @generated + */ + protected EClass eStaticClass() { + return GraphPackage.Literals.EGRAPH; + } + + /** + * + * + * @generated + */ + public ECollection getNodes() { + if (nodes != null && nodes.eIsProxy()) { + InternalEObject oldNodes = (InternalEObject)nodes; + nodes = (ECollection)eResolveProxy(oldNodes); + if (nodes != oldNodes) { + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.RESOLVE, GraphPackage.EGRAPH__NODES, oldNodes, nodes)); + } + } + return nodes; + } + + /** + * + * + * @generated + */ + public ECollection basicGetNodes() { + return nodes; + } + + /** + * + * + * @generated + */ + public void setNodes(ECollection newNodes) { + ECollection oldNodes = nodes; + nodes = newNodes; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, GraphPackage.EGRAPH__NODES, oldNodes, nodes)); + } + + /** + * + * + * @generated + */ + public ERelation getEdges() { + return edges; + } + + /** + * + * + * @generated + */ + public NotificationChain basicSetEdges(ERelation newEdges, NotificationChain msgs) { + ERelation oldEdges = edges; + edges = newEdges; + if (eNotificationRequired()) { + ENotificationImpl notification = new ENotificationImpl(this, Notification.SET, GraphPackage.EGRAPH__EDGES, oldEdges, newEdges); + if (msgs == null) msgs = notification; else msgs.add(notification); + } + return msgs; + } + + /** + * + * + * @generated + */ + public void setEdges(ERelation newEdges) { + if (newEdges != edges) { + NotificationChain msgs = null; + if (edges != null) + msgs = ((InternalEObject)edges).eInverseRemove(this, EOPPOSITE_FEATURE_BASE - GraphPackage.EGRAPH__EDGES, null, msgs); + if (newEdges != null) + msgs = ((InternalEObject)newEdges).eInverseAdd(this, EOPPOSITE_FEATURE_BASE - GraphPackage.EGRAPH__EDGES, null, msgs); + msgs = basicSetEdges(newEdges, msgs); + if (msgs != null) msgs.dispatch(); + } + else if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, GraphPackage.EGRAPH__EDGES, newEdges, newEdges)); + } + + /** + * + * + * @generated + */ + public NotificationChain eInverseRemove(InternalEObject otherEnd, int featureID, NotificationChain msgs) { + switch (featureID) { + case GraphPackage.EGRAPH__EDGES: + return basicSetEdges(null, msgs); + } + return super.eInverseRemove(otherEnd, featureID, msgs); + } + + /** + * + * + * @generated + */ + public Object eGet(int featureID, boolean resolve, boolean coreType) { + switch (featureID) { + case GraphPackage.EGRAPH__NODES: + if (resolve) return getNodes(); + return basicGetNodes(); + case GraphPackage.EGRAPH__EDGES: + return getEdges(); + } + return super.eGet(featureID, resolve, coreType); + } + + /** + * + * + * @generated + */ + public void eSet(int featureID, Object newValue) { + switch (featureID) { + case GraphPackage.EGRAPH__NODES: + setNodes((ECollection)newValue); + return; + case GraphPackage.EGRAPH__EDGES: + setEdges((ERelation)newValue); + return; + } + super.eSet(featureID, newValue); + } + + /** + * + * + * @generated + */ + public void eUnset(int featureID) { + switch (featureID) { + case GraphPackage.EGRAPH__NODES: + setNodes((ECollection)null); + return; + case GraphPackage.EGRAPH__EDGES: + setEdges((ERelation)null); + return; + } + super.eUnset(featureID); + } + + /** + * + * + * @generated + */ + public boolean eIsSet(int featureID) { + switch (featureID) { + case GraphPackage.EGRAPH__NODES: + return nodes != null; + case GraphPackage.EGRAPH__EDGES: + return edges != null; + } + return super.eIsSet(featureID); + } + +} //EGraphImpl \ No newline at end of file diff --git a/com.ibm.wala.emf/src/com/ibm/wala/ecore/graph/impl/ETreeImpl.java b/com.ibm.wala.emf/src/com/ibm/wala/ecore/graph/impl/ETreeImpl.java new file mode 100644 index 000000000..45b9e97fc --- /dev/null +++ b/com.ibm.wala.emf/src/com/ibm/wala/ecore/graph/impl/ETreeImpl.java @@ -0,0 +1,42 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.graph.impl; + +import com.ibm.wala.ecore.graph.ETree; +import com.ibm.wala.ecore.graph.GraphPackage; + +import org.eclipse.emf.ecore.EClass; + +/** + * + * An implementation of the model object 'ETree'. + * + *

                              + *

                              + * + * @generated + */ +public class ETreeImpl extends EGraphImpl implements ETree { + /** + * + * + * @generated + */ + protected ETreeImpl() { + super(); + } + + /** + * + * + * @generated + */ + protected EClass eStaticClass() { + return GraphPackage.Literals.ETREE; + } + +} //ETreeImpl \ No newline at end of file diff --git a/com.ibm.wala.emf/src/com/ibm/wala/ecore/graph/impl/GraphFactoryImpl.java b/com.ibm.wala.emf/src/com/ibm/wala/ecore/graph/impl/GraphFactoryImpl.java new file mode 100644 index 000000000..7b4e5867e --- /dev/null +++ b/com.ibm.wala.emf/src/com/ibm/wala/ecore/graph/impl/GraphFactoryImpl.java @@ -0,0 +1,108 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.graph.impl; + +import com.ibm.wala.ecore.graph.*; + +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EPackage; + +import org.eclipse.emf.ecore.impl.EFactoryImpl; + +import org.eclipse.emf.ecore.plugin.EcorePlugin; + +/** + * + * An implementation of the model Factory. + * + * @generated + */ +public class GraphFactoryImpl extends EFactoryImpl implements GraphFactory { + /** + * Creates the default factory implementation. + * + * + * @generated + */ + public static GraphFactory init() { + try { + GraphFactory theGraphFactory = (GraphFactory)EPackage.Registry.INSTANCE.getEFactory("http:///com/ibm/wala/wala.ecore.graph"); + if (theGraphFactory != null) { + return theGraphFactory; + } + } + catch (Exception exception) { + EcorePlugin.INSTANCE.log(exception); + } + return new GraphFactoryImpl(); + } + + /** + * Creates an instance of the factory. + * + * + * @generated + */ + public GraphFactoryImpl() { + super(); + } + + /** + * + * + * @generated + */ + public EObject create(EClass eClass) { + switch (eClass.getClassifierID()) { + case GraphPackage.EGRAPH: return createEGraph(); + case GraphPackage.ETREE: return createETree(); + default: + throw new IllegalArgumentException("The class '" + eClass.getName() + "' is not a valid classifier"); + } + } + + /** + * + * + * @generated + */ + public EGraph createEGraph() { + EGraphImpl eGraph = new EGraphImpl(); + return eGraph; + } + + /** + * + * + * @generated + */ + public ETree createETree() { + ETreeImpl eTree = new ETreeImpl(); + return eTree; + } + + /** + * + * + * @generated + */ + public GraphPackage getGraphPackage() { + return (GraphPackage)getEPackage(); + } + + /** + * + * + * @deprecated + * @generated + */ + public static GraphPackage getPackage() { + return GraphPackage.eINSTANCE; + } + +} //GraphFactoryImpl diff --git a/com.ibm.wala.emf/src/com/ibm/wala/ecore/graph/impl/GraphPackageImpl.java b/com.ibm.wala.emf/src/com/ibm/wala/ecore/graph/impl/GraphPackageImpl.java new file mode 100644 index 000000000..0e51721f3 --- /dev/null +++ b/com.ibm.wala.emf/src/com/ibm/wala/ecore/graph/impl/GraphPackageImpl.java @@ -0,0 +1,278 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.graph.impl; + +import com.ibm.wala.ecore.common.CommonPackage; + +import com.ibm.wala.ecore.common.impl.CommonPackageImpl; + +import com.ibm.wala.ecore.graph.EGraph; +import com.ibm.wala.ecore.graph.ETree; +import com.ibm.wala.ecore.graph.GraphFactory; +import com.ibm.wala.ecore.graph.GraphPackage; + +import com.ibm.wala.ecore.j2ee.scope.J2EEScopePackage; + +import com.ibm.wala.ecore.j2ee.scope.impl.J2EEScopePackageImpl; + +import com.ibm.wala.ecore.java.JavaPackage; + +import com.ibm.wala.ecore.java.callGraph.CallGraphPackage; + +import com.ibm.wala.ecore.java.callGraph.impl.CallGraphPackageImpl; + +import com.ibm.wala.ecore.java.impl.JavaPackageImpl; + +import com.ibm.wala.ecore.java.pointerAnalysis.PointerAnalysisPackage; + +import com.ibm.wala.ecore.java.pointerAnalysis.impl.PointerAnalysisPackageImpl; + +import com.ibm.wala.ecore.java.scope.JavaScopePackage; + +import com.ibm.wala.ecore.java.scope.impl.JavaScopePackageImpl; + +import com.ibm.wala.ecore.perf.PerfPackage; + +import com.ibm.wala.ecore.perf.impl.PerfPackageImpl; + +import com.ibm.wala.ecore.regex.RegexPackage; + +import com.ibm.wala.ecore.regex.impl.RegexPackageImpl; + +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EPackage; +import org.eclipse.emf.ecore.EReference; + +import org.eclipse.emf.ecore.impl.EPackageImpl; + +/** + * + * An implementation of the model Package. + * + * @generated + */ +public class GraphPackageImpl extends EPackageImpl implements GraphPackage { + /** + * + * + * @generated + */ + private EClass eGraphEClass = null; + + /** + * + * + * @generated + */ + private EClass eTreeEClass = null; + + /** + * Creates an instance of the model Package, registered with + * {@link org.eclipse.emf.ecore.EPackage.Registry EPackage.Registry} by the package + * package URI value. + *

                              Note: the correct way to create the package is via the static + * factory method {@link #init init()}, which also performs + * initialization of the package, or returns the registered package, + * if one already exists. + * + * + * @see org.eclipse.emf.ecore.EPackage.Registry + * @see com.ibm.wala.ecore.graph.GraphPackage#eNS_URI + * @see #init() + * @generated + */ + private GraphPackageImpl() { + super(eNS_URI, GraphFactory.eINSTANCE); + } + + /** + * + * + * @generated + */ + private static boolean isInited = false; + + /** + * Creates, registers, and initializes the Package for this + * model, and for any others upon which it depends. Simple + * dependencies are satisfied by calling this method on all + * dependent packages before doing anything else. This method drives + * initialization for interdependent packages directly, in parallel + * with this package, itself. + *

                              Of this package and its interdependencies, all packages which + * have not yet been registered by their URI values are first created + * and registered. The packages are then initialized in two steps: + * meta-model objects for all of the packages are created before any + * are initialized, since one package's meta-model objects may refer to + * those of another. + *

                              Invocation of this method will not affect any packages that have + * already been initialized. + * + * + * @see #eNS_URI + * @see #createPackageContents() + * @see #initializePackageContents() + * @generated + */ + public static GraphPackage init() { + if (isInited) return (GraphPackage)EPackage.Registry.INSTANCE.getEPackage(GraphPackage.eNS_URI); + + // Obtain or create and register package + GraphPackageImpl theGraphPackage = (GraphPackageImpl)(EPackage.Registry.INSTANCE.getEPackage(eNS_URI) instanceof GraphPackageImpl ? EPackage.Registry.INSTANCE.getEPackage(eNS_URI) : new GraphPackageImpl()); + + isInited = true; + + // Obtain or create and register interdependencies + CommonPackageImpl theCommonPackage = (CommonPackageImpl)(EPackage.Registry.INSTANCE.getEPackage(CommonPackage.eNS_URI) instanceof CommonPackageImpl ? EPackage.Registry.INSTANCE.getEPackage(CommonPackage.eNS_URI) : CommonPackage.eINSTANCE); + RegexPackageImpl theRegexPackage = (RegexPackageImpl)(EPackage.Registry.INSTANCE.getEPackage(RegexPackage.eNS_URI) instanceof RegexPackageImpl ? EPackage.Registry.INSTANCE.getEPackage(RegexPackage.eNS_URI) : RegexPackage.eINSTANCE); + PerfPackageImpl thePerfPackage = (PerfPackageImpl)(EPackage.Registry.INSTANCE.getEPackage(PerfPackage.eNS_URI) instanceof PerfPackageImpl ? EPackage.Registry.INSTANCE.getEPackage(PerfPackage.eNS_URI) : PerfPackage.eINSTANCE); + JavaPackageImpl theJavaPackage = (JavaPackageImpl)(EPackage.Registry.INSTANCE.getEPackage(JavaPackage.eNS_URI) instanceof JavaPackageImpl ? EPackage.Registry.INSTANCE.getEPackage(JavaPackage.eNS_URI) : JavaPackage.eINSTANCE); + CallGraphPackageImpl theCallGraphPackage = (CallGraphPackageImpl)(EPackage.Registry.INSTANCE.getEPackage(CallGraphPackage.eNS_URI) instanceof CallGraphPackageImpl ? EPackage.Registry.INSTANCE.getEPackage(CallGraphPackage.eNS_URI) : CallGraphPackage.eINSTANCE); + PointerAnalysisPackageImpl thePointerAnalysisPackage = (PointerAnalysisPackageImpl)(EPackage.Registry.INSTANCE.getEPackage(PointerAnalysisPackage.eNS_URI) instanceof PointerAnalysisPackageImpl ? EPackage.Registry.INSTANCE.getEPackage(PointerAnalysisPackage.eNS_URI) : PointerAnalysisPackage.eINSTANCE); + JavaScopePackageImpl theJavaScopePackage = (JavaScopePackageImpl)(EPackage.Registry.INSTANCE.getEPackage(JavaScopePackage.eNS_URI) instanceof JavaScopePackageImpl ? EPackage.Registry.INSTANCE.getEPackage(JavaScopePackage.eNS_URI) : JavaScopePackage.eINSTANCE); + J2EEScopePackageImpl theJ2EEScopePackage = (J2EEScopePackageImpl)(EPackage.Registry.INSTANCE.getEPackage(J2EEScopePackage.eNS_URI) instanceof J2EEScopePackageImpl ? EPackage.Registry.INSTANCE.getEPackage(J2EEScopePackage.eNS_URI) : J2EEScopePackage.eINSTANCE); + + // Create package meta-data objects + theGraphPackage.createPackageContents(); + theCommonPackage.createPackageContents(); + theRegexPackage.createPackageContents(); + thePerfPackage.createPackageContents(); + theJavaPackage.createPackageContents(); + theCallGraphPackage.createPackageContents(); + thePointerAnalysisPackage.createPackageContents(); + theJavaScopePackage.createPackageContents(); + theJ2EEScopePackage.createPackageContents(); + + // Initialize created meta-data + theGraphPackage.initializePackageContents(); + theCommonPackage.initializePackageContents(); + theRegexPackage.initializePackageContents(); + thePerfPackage.initializePackageContents(); + theJavaPackage.initializePackageContents(); + theCallGraphPackage.initializePackageContents(); + thePointerAnalysisPackage.initializePackageContents(); + theJavaScopePackage.initializePackageContents(); + theJ2EEScopePackage.initializePackageContents(); + + // Mark meta-data to indicate it can't be changed + theGraphPackage.freeze(); + + return theGraphPackage; + } + + /** + * + * + * @generated + */ + public EClass getEGraph() { + return eGraphEClass; + } + + /** + * + * + * @generated + */ + public EReference getEGraph_Nodes() { + return (EReference)eGraphEClass.getEStructuralFeatures().get(0); + } + + /** + * + * + * @generated + */ + public EReference getEGraph_Edges() { + return (EReference)eGraphEClass.getEStructuralFeatures().get(1); + } + + /** + * + * + * @generated + */ + public EClass getETree() { + return eTreeEClass; + } + + /** + * + * + * @generated + */ + public GraphFactory getGraphFactory() { + return (GraphFactory)getEFactoryInstance(); + } + + /** + * + * + * @generated + */ + private boolean isCreated = false; + + /** + * Creates the meta-model objects for the package. This method is + * guarded to have no affect on any invocation but its first. + * + * + * @generated + */ + public void createPackageContents() { + if (isCreated) return; + isCreated = true; + + // Create classes and their features + eGraphEClass = createEClass(EGRAPH); + createEReference(eGraphEClass, EGRAPH__NODES); + createEReference(eGraphEClass, EGRAPH__EDGES); + + eTreeEClass = createEClass(ETREE); + } + + /** + * + * + * @generated + */ + private boolean isInitialized = false; + + /** + * Complete the initialization of the package and its meta-model. This + * method is guarded to have no affect on any invocation but its first. + * + * + * @generated + */ + public void initializePackageContents() { + if (isInitialized) return; + isInitialized = true; + + // Initialize package + setName(eNAME); + setNsPrefix(eNS_PREFIX); + setNsURI(eNS_URI); + + // Obtain other dependent packages + CommonPackage theCommonPackage = (CommonPackage)EPackage.Registry.INSTANCE.getEPackage(CommonPackage.eNS_URI); + + // Add supertypes to classes + eTreeEClass.getESuperTypes().add(this.getEGraph()); + + // Initialize classes and features; add operations and parameters + initEClass(eGraphEClass, EGraph.class, "EGraph", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); + initEReference(getEGraph_Nodes(), theCommonPackage.getECollection(), null, "nodes", null, 1, 1, EGraph.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_COMPOSITE, IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); + initEReference(getEGraph_Edges(), theCommonPackage.getERelation(), null, "edges", null, 1, 1, EGraph.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, IS_COMPOSITE, !IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); + + initEClass(eTreeEClass, ETree.class, "ETree", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); + + // Create resource + createResource(eNS_URI); + } + +} //GraphPackageImpl diff --git a/com.ibm.wala.emf/src/com/ibm/wala/ecore/graph/util/GraphAdapterFactory.java b/com.ibm.wala.emf/src/com/ibm/wala/ecore/graph/util/GraphAdapterFactory.java new file mode 100644 index 000000000..6ae04760c --- /dev/null +++ b/com.ibm.wala.emf/src/com/ibm/wala/ecore/graph/util/GraphAdapterFactory.java @@ -0,0 +1,137 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.graph.util; + +import com.ibm.wala.ecore.graph.*; + +import org.eclipse.emf.common.notify.Adapter; +import org.eclipse.emf.common.notify.Notifier; + +import org.eclipse.emf.common.notify.impl.AdapterFactoryImpl; + +import org.eclipse.emf.ecore.EObject; + +/** + * + * The Adapter Factory for the model. + * It provides an adapter createXXX method for each class of the model. + * + * @see com.ibm.wala.ecore.graph.GraphPackage + * @generated + */ +public class GraphAdapterFactory extends AdapterFactoryImpl { + /** + * The cached model package. + * + * + * @generated + */ + protected static GraphPackage modelPackage; + + /** + * Creates an instance of the adapter factory. + * + * + * @generated + */ + public GraphAdapterFactory() { + if (modelPackage == null) { + modelPackage = GraphPackage.eINSTANCE; + } + } + + /** + * Returns whether this factory is applicable for the type of the object. + * + * This implementation returns true if the object is either the model's package or is an instance object of the model. + * + * @return whether this factory is applicable for the type of the object. + * @generated + */ + public boolean isFactoryForType(Object object) { + if (object == modelPackage) { + return true; + } + if (object instanceof EObject) { + return ((EObject)object).eClass().getEPackage() == modelPackage; + } + return false; + } + + /** + * The switch the delegates to the createXXX methods. + * + * + * @generated + */ + protected GraphSwitch modelSwitch = + new GraphSwitch() { + public Object caseEGraph(EGraph object) { + return createEGraphAdapter(); + } + public Object caseETree(ETree object) { + return createETreeAdapter(); + } + public Object defaultCase(EObject object) { + return createEObjectAdapter(); + } + }; + + /** + * Creates an adapter for the target. + * + * + * @param target the object to adapt. + * @return the adapter for the target. + * @generated + */ + public Adapter createAdapter(Notifier target) { + return (Adapter)modelSwitch.doSwitch((EObject)target); + } + + + /** + * Creates a new adapter for an object of class '{@link com.ibm.wala.ecore.graph.EGraph EGraph}'. + * + * This default implementation returns null so that we can easily ignore cases; + * it's useful to ignore a case when inheritance will catch all the cases anyway. + * + * @return the new adapter. + * @see com.ibm.wala.ecore.graph.EGraph + * @generated + */ + public Adapter createEGraphAdapter() { + return null; + } + + /** + * Creates a new adapter for an object of class '{@link com.ibm.wala.ecore.graph.ETree ETree}'. + * + * This default implementation returns null so that we can easily ignore cases; + * it's useful to ignore a case when inheritance will catch all the cases anyway. + * + * @return the new adapter. + * @see com.ibm.wala.ecore.graph.ETree + * @generated + */ + public Adapter createETreeAdapter() { + return null; + } + + /** + * Creates a new adapter for the default case. + * + * This default implementation returns null. + * + * @return the new adapter. + * @generated + */ + public Adapter createEObjectAdapter() { + return null; + } + +} //GraphAdapterFactory diff --git a/com.ibm.wala.emf/src/com/ibm/wala/ecore/graph/util/GraphSwitch.java b/com.ibm.wala.emf/src/com/ibm/wala/ecore/graph/util/GraphSwitch.java new file mode 100644 index 000000000..fc5ed43cc --- /dev/null +++ b/com.ibm.wala.emf/src/com/ibm/wala/ecore/graph/util/GraphSwitch.java @@ -0,0 +1,152 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.graph.util; + +import com.ibm.wala.ecore.graph.*; + +import java.util.List; + +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EObject; + +/** + * + * The Switch for the model's inheritance hierarchy. + * It supports the call {@link #doSwitch(EObject) doSwitch(object)} + * to invoke the caseXXX method for each class of the model, + * starting with the actual class of the object + * and proceeding up the inheritance hierarchy + * until a non-null result is returned, + * which is the result of the switch. + * + * @see com.ibm.wala.ecore.graph.GraphPackage + * @generated + */ +public class GraphSwitch { + /** + * The cached model package + * + * + * @generated + */ + protected static GraphPackage modelPackage; + + /** + * Creates an instance of the switch. + * + * + * @generated + */ + public GraphSwitch() { + if (modelPackage == null) { + modelPackage = GraphPackage.eINSTANCE; + } + } + + /** + * Calls caseXXX for each class of the model until one returns a non null result; it yields that result. + * + * + * @return the first non-null result returned by a caseXXX call. + * @generated + */ + public Object doSwitch(EObject theEObject) { + return doSwitch(theEObject.eClass(), theEObject); + } + + /** + * Calls caseXXX for each class of the model until one returns a non null result; it yields that result. + * + * + * @return the first non-null result returned by a caseXXX call. + * @generated + */ + protected Object doSwitch(EClass theEClass, EObject theEObject) { + if (theEClass.eContainer() == modelPackage) { + return doSwitch(theEClass.getClassifierID(), theEObject); + } + else { + List eSuperTypes = theEClass.getESuperTypes(); + return + eSuperTypes.isEmpty() ? + defaultCase(theEObject) : + doSwitch((EClass)eSuperTypes.get(0), theEObject); + } + } + + /** + * Calls caseXXX for each class of the model until one returns a non null result; it yields that result. + * + * + * @return the first non-null result returned by a caseXXX call. + * @generated + */ + protected Object doSwitch(int classifierID, EObject theEObject) { + switch (classifierID) { + case GraphPackage.EGRAPH: { + EGraph eGraph = (EGraph)theEObject; + Object result = caseEGraph(eGraph); + if (result == null) result = defaultCase(theEObject); + return result; + } + case GraphPackage.ETREE: { + ETree eTree = (ETree)theEObject; + Object result = caseETree(eTree); + if (result == null) result = caseEGraph(eTree); + if (result == null) result = defaultCase(theEObject); + return result; + } + default: return defaultCase(theEObject); + } + } + + /** + * Returns the result of interpretting the object as an instance of 'EGraph'. + * + * This implementation returns null; + * returning a non-null result will terminate the switch. + * + * @param object the target of the switch. + * @return the result of interpretting the object as an instance of 'EGraph'. + * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject) + * @generated + */ + public Object caseEGraph(EGraph object) { + return null; + } + + /** + * Returns the result of interpretting the object as an instance of 'ETree'. + * + * This implementation returns null; + * returning a non-null result will terminate the switch. + * + * @param object the target of the switch. + * @return the result of interpretting the object as an instance of 'ETree'. + * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject) + * @generated + */ + public Object caseETree(ETree object) { + return null; + } + + /** + * Returns the result of interpretting the object as an instance of 'EObject'. + * + * This implementation returns null; + * returning a non-null result will terminate the switch, but this is the last case anyway. + * + * @param object the target of the switch. + * @return the result of interpretting the object as an instance of 'EObject'. + * @see #doSwitch(org.eclipse.emf.ecore.EObject) + * @generated + */ + public Object defaultCase(EObject object) { + return null; + } + +} //GraphSwitch diff --git a/com.ibm.wala.emf/src/com/ibm/wala/ecore/j2ee/scope/EEarFile.java b/com.ibm.wala.emf/src/com/ibm/wala/ecore/j2ee/scope/EEarFile.java new file mode 100644 index 000000000..d139d1886 --- /dev/null +++ b/com.ibm.wala.emf/src/com/ibm/wala/ecore/j2ee/scope/EEarFile.java @@ -0,0 +1,22 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.j2ee.scope; + +import com.ibm.wala.ecore.java.scope.EJarFile; + +/** + * + * A representation of the model object 'EEar File'. + * + * + * + * @see com.ibm.wala.ecore.j2ee.scope.J2EEScopePackage#getEEarFile() + * @model + * @generated + */ +public interface EEarFile extends EJarFile { +} // EEarFile \ No newline at end of file diff --git a/com.ibm.wala.emf/src/com/ibm/wala/ecore/j2ee/scope/EJ2EEAnalysisScope.java b/com.ibm.wala.emf/src/com/ibm/wala/ecore/j2ee/scope/EJ2EEAnalysisScope.java new file mode 100644 index 000000000..e99cc38fb --- /dev/null +++ b/com.ibm.wala.emf/src/com/ibm/wala/ecore/j2ee/scope/EJ2EEAnalysisScope.java @@ -0,0 +1,22 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.j2ee.scope; + +import com.ibm.wala.ecore.java.scope.EJavaAnalysisScope; + +/** + * + * A representation of the model object 'EJ2EE Analysis Scope'. + * + * + * + * @see com.ibm.wala.ecore.j2ee.scope.J2EEScopePackage#getEJ2EEAnalysisScope() + * @model + * @generated + */ +public interface EJ2EEAnalysisScope extends EJavaAnalysisScope { +} // EJ2EEAnalysisScope \ No newline at end of file diff --git a/com.ibm.wala.emf/src/com/ibm/wala/ecore/j2ee/scope/EWarFile.java b/com.ibm.wala.emf/src/com/ibm/wala/ecore/j2ee/scope/EWarFile.java new file mode 100644 index 000000000..6b5aef13d --- /dev/null +++ b/com.ibm.wala.emf/src/com/ibm/wala/ecore/j2ee/scope/EWarFile.java @@ -0,0 +1,22 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.j2ee.scope; + +import com.ibm.wala.ecore.java.scope.EJarFile; + +/** + * + * A representation of the model object 'EWar File'. + * + * + * + * @see com.ibm.wala.ecore.j2ee.scope.J2EEScopePackage#getEWarFile() + * @model + * @generated + */ +public interface EWarFile extends EJarFile { +} // EWarFile \ No newline at end of file diff --git a/com.ibm.wala.emf/src/com/ibm/wala/ecore/j2ee/scope/J2EEScopeFactory.java b/com.ibm.wala.emf/src/com/ibm/wala/ecore/j2ee/scope/J2EEScopeFactory.java new file mode 100644 index 000000000..aebdf01fa --- /dev/null +++ b/com.ibm.wala.emf/src/com/ibm/wala/ecore/j2ee/scope/J2EEScopeFactory.java @@ -0,0 +1,64 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.j2ee.scope; + +import org.eclipse.emf.ecore.EFactory; + +/** + * + * The Factory for the model. + * It provides a create method for each non-abstract class of the model. + * + * @see com.ibm.wala.ecore.j2ee.scope.J2EEScopePackage + * @generated + */ +public interface J2EEScopeFactory extends EFactory { + /** + * The singleton instance of the factory. + * + * + * @generated + */ + J2EEScopeFactory eINSTANCE = com.ibm.wala.ecore.j2ee.scope.impl.J2EEScopeFactoryImpl.init(); + + /** + * Returns a new object of class 'EJ2EE Analysis Scope'. + * + * + * @return a new object of class 'EJ2EE Analysis Scope'. + * @generated + */ + EJ2EEAnalysisScope createEJ2EEAnalysisScope(); + + /** + * Returns a new object of class 'EEar File'. + * + * + * @return a new object of class 'EEar File'. + * @generated + */ + EEarFile createEEarFile(); + + /** + * Returns a new object of class 'EWar File'. + * + * + * @return a new object of class 'EWar File'. + * @generated + */ + EWarFile createEWarFile(); + + /** + * Returns the package supported by this factory. + * + * + * @return the package supported by this factory. + * @generated + */ + J2EEScopePackage getJ2EEScopePackage(); + +} //J2EEScopeFactory diff --git a/com.ibm.wala.emf/src/com/ibm/wala/ecore/j2ee/scope/J2EEScopePackage.java b/com.ibm.wala.emf/src/com/ibm/wala/ecore/j2ee/scope/J2EEScopePackage.java new file mode 100644 index 000000000..9c356866e --- /dev/null +++ b/com.ibm.wala.emf/src/com/ibm/wala/ecore/j2ee/scope/J2EEScopePackage.java @@ -0,0 +1,240 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.j2ee.scope; + +import com.ibm.wala.ecore.java.scope.JavaScopePackage; + +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EPackage; + +/** + * + * The Package for the model. + * It contains accessors for the meta objects to represent + *

                                + *
                              • each class,
                              • + *
                              • each feature of each class,
                              • + *
                              • each enum,
                              • + *
                              • and each data type
                              • + *
                              + * + * @see com.ibm.wala.ecore.j2ee.scope.J2EEScopeFactory + * @model kind="package" + * @generated + */ +public interface J2EEScopePackage extends EPackage { + /** + * The package name. + * + * + * @generated + */ + String eNAME = "scope"; + + /** + * The package namespace URI. + * + * + * @generated + */ + String eNS_URI = "http:///com/ibm/wala/wala.ecore.j2ee.scope"; + + /** + * The package namespace name. + * + * + * @generated + */ + String eNS_PREFIX = "com.ibm.wala.j2ee.scope"; + + /** + * The singleton instance of the package. + * + * + * @generated + */ + J2EEScopePackage eINSTANCE = com.ibm.wala.ecore.j2ee.scope.impl.J2EEScopePackageImpl.init(); + + /** + * The meta object id for the '{@link com.ibm.wala.ecore.j2ee.scope.impl.EJ2EEAnalysisScopeImpl EJ2EE Analysis Scope}' class. + * + * + * @see com.ibm.wala.ecore.j2ee.scope.impl.EJ2EEAnalysisScopeImpl + * @see com.ibm.wala.ecore.j2ee.scope.impl.J2EEScopePackageImpl#getEJ2EEAnalysisScope() + * @generated + */ + int EJ2EE_ANALYSIS_SCOPE = 0; + + /** + * The feature id for the 'Loaders' containment reference list. + * + * + * @generated + * @ordered + */ + int EJ2EE_ANALYSIS_SCOPE__LOADERS = JavaScopePackage.EJAVA_ANALYSIS_SCOPE__LOADERS; + + /** + * The feature id for the 'Exclusion File Name' attribute. + * + * + * @generated + * @ordered + */ + int EJ2EE_ANALYSIS_SCOPE__EXCLUSION_FILE_NAME = JavaScopePackage.EJAVA_ANALYSIS_SCOPE__EXCLUSION_FILE_NAME; + + /** + * The number of structural features of the 'EJ2EE Analysis Scope' class. + * + * + * @generated + * @ordered + */ + int EJ2EE_ANALYSIS_SCOPE_FEATURE_COUNT = JavaScopePackage.EJAVA_ANALYSIS_SCOPE_FEATURE_COUNT + 0; + + /** + * The meta object id for the '{@link com.ibm.wala.ecore.j2ee.scope.impl.EEarFileImpl EEar File}' class. + * + * + * @see com.ibm.wala.ecore.j2ee.scope.impl.EEarFileImpl + * @see com.ibm.wala.ecore.j2ee.scope.impl.J2EEScopePackageImpl#getEEarFile() + * @generated + */ + int EEAR_FILE = 1; + + /** + * The feature id for the 'Url' attribute. + * + * + * @generated + * @ordered + */ + int EEAR_FILE__URL = JavaScopePackage.EJAR_FILE__URL; + + /** + * The number of structural features of the 'EEar File' class. + * + * + * @generated + * @ordered + */ + int EEAR_FILE_FEATURE_COUNT = JavaScopePackage.EJAR_FILE_FEATURE_COUNT + 0; + + /** + * The meta object id for the '{@link com.ibm.wala.ecore.j2ee.scope.impl.EWarFileImpl EWar File}' class. + * + * + * @see com.ibm.wala.ecore.j2ee.scope.impl.EWarFileImpl + * @see com.ibm.wala.ecore.j2ee.scope.impl.J2EEScopePackageImpl#getEWarFile() + * @generated + */ + int EWAR_FILE = 2; + + /** + * The feature id for the 'Url' attribute. + * + * + * @generated + * @ordered + */ + int EWAR_FILE__URL = JavaScopePackage.EJAR_FILE__URL; + + /** + * The number of structural features of the 'EWar File' class. + * + * + * @generated + * @ordered + */ + int EWAR_FILE_FEATURE_COUNT = JavaScopePackage.EJAR_FILE_FEATURE_COUNT + 0; + + + /** + * Returns the meta object for class '{@link com.ibm.wala.ecore.j2ee.scope.EJ2EEAnalysisScope EJ2EE Analysis Scope}'. + * + * + * @return the meta object for class 'EJ2EE Analysis Scope'. + * @see com.ibm.wala.ecore.j2ee.scope.EJ2EEAnalysisScope + * @generated + */ + EClass getEJ2EEAnalysisScope(); + + /** + * Returns the meta object for class '{@link com.ibm.wala.ecore.j2ee.scope.EEarFile EEar File}'. + * + * + * @return the meta object for class 'EEar File'. + * @see com.ibm.wala.ecore.j2ee.scope.EEarFile + * @generated + */ + EClass getEEarFile(); + + /** + * Returns the meta object for class '{@link com.ibm.wala.ecore.j2ee.scope.EWarFile EWar File}'. + * + * + * @return the meta object for class 'EWar File'. + * @see com.ibm.wala.ecore.j2ee.scope.EWarFile + * @generated + */ + EClass getEWarFile(); + + /** + * Returns the factory that creates the instances of the model. + * + * + * @return the factory that creates the instances of the model. + * @generated + */ + J2EEScopeFactory getJ2EEScopeFactory(); + + /** + * + * Defines literals for the meta objects that represent + *
                                + *
                              • each class,
                              • + *
                              • each feature of each class,
                              • + *
                              • each enum,
                              • + *
                              • and each data type
                              • + *
                              + * + * @generated + */ + interface Literals { + /** + * The meta object literal for the '{@link com.ibm.wala.ecore.j2ee.scope.impl.EJ2EEAnalysisScopeImpl EJ2EE Analysis Scope}' class. + * + * + * @see com.ibm.wala.ecore.j2ee.scope.impl.EJ2EEAnalysisScopeImpl + * @see com.ibm.wala.ecore.j2ee.scope.impl.J2EEScopePackageImpl#getEJ2EEAnalysisScope() + * @generated + */ + EClass EJ2EE_ANALYSIS_SCOPE = eINSTANCE.getEJ2EEAnalysisScope(); + + /** + * The meta object literal for the '{@link com.ibm.wala.ecore.j2ee.scope.impl.EEarFileImpl EEar File}' class. + * + * + * @see com.ibm.wala.ecore.j2ee.scope.impl.EEarFileImpl + * @see com.ibm.wala.ecore.j2ee.scope.impl.J2EEScopePackageImpl#getEEarFile() + * @generated + */ + EClass EEAR_FILE = eINSTANCE.getEEarFile(); + + /** + * The meta object literal for the '{@link com.ibm.wala.ecore.j2ee.scope.impl.EWarFileImpl EWar File}' class. + * + * + * @see com.ibm.wala.ecore.j2ee.scope.impl.EWarFileImpl + * @see com.ibm.wala.ecore.j2ee.scope.impl.J2EEScopePackageImpl#getEWarFile() + * @generated + */ + EClass EWAR_FILE = eINSTANCE.getEWarFile(); + + } + +} //J2EEScopePackage diff --git a/com.ibm.wala.emf/src/com/ibm/wala/ecore/j2ee/scope/impl/EEarFileImpl.java b/com.ibm.wala.emf/src/com/ibm/wala/ecore/j2ee/scope/impl/EEarFileImpl.java new file mode 100644 index 000000000..f16ae8655 --- /dev/null +++ b/com.ibm.wala.emf/src/com/ibm/wala/ecore/j2ee/scope/impl/EEarFileImpl.java @@ -0,0 +1,44 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.j2ee.scope.impl; + +import com.ibm.wala.ecore.j2ee.scope.EEarFile; +import com.ibm.wala.ecore.j2ee.scope.J2EEScopePackage; + +import com.ibm.wala.ecore.java.scope.impl.EJarFileImpl; + +import org.eclipse.emf.ecore.EClass; + +/** + * + * An implementation of the model object 'EEar File'. + * + *

                              + *

                              + * + * @generated + */ +public class EEarFileImpl extends EJarFileImpl implements EEarFile { + /** + * + * + * @generated + */ + protected EEarFileImpl() { + super(); + } + + /** + * + * + * @generated + */ + protected EClass eStaticClass() { + return J2EEScopePackage.Literals.EEAR_FILE; + } + +} //EEarFileImpl \ No newline at end of file diff --git a/com.ibm.wala.emf/src/com/ibm/wala/ecore/j2ee/scope/impl/EJ2EEAnalysisScopeImpl.java b/com.ibm.wala.emf/src/com/ibm/wala/ecore/j2ee/scope/impl/EJ2EEAnalysisScopeImpl.java new file mode 100644 index 000000000..cf7f1e21c --- /dev/null +++ b/com.ibm.wala.emf/src/com/ibm/wala/ecore/j2ee/scope/impl/EJ2EEAnalysisScopeImpl.java @@ -0,0 +1,44 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.j2ee.scope.impl; + +import com.ibm.wala.ecore.j2ee.scope.EJ2EEAnalysisScope; +import com.ibm.wala.ecore.j2ee.scope.J2EEScopePackage; + +import com.ibm.wala.ecore.java.scope.impl.EJavaAnalysisScopeImpl; + +import org.eclipse.emf.ecore.EClass; + +/** + * + * An implementation of the model object 'EJ2EE Analysis Scope'. + * + *

                              + *

                              + * + * @generated + */ +public class EJ2EEAnalysisScopeImpl extends EJavaAnalysisScopeImpl implements EJ2EEAnalysisScope { + /** + * + * + * @generated + */ + protected EJ2EEAnalysisScopeImpl() { + super(); + } + + /** + * + * + * @generated + */ + protected EClass eStaticClass() { + return J2EEScopePackage.Literals.EJ2EE_ANALYSIS_SCOPE; + } + +} //EJ2EEAnalysisScopeImpl \ No newline at end of file diff --git a/com.ibm.wala.emf/src/com/ibm/wala/ecore/j2ee/scope/impl/EWarFileImpl.java b/com.ibm.wala.emf/src/com/ibm/wala/ecore/j2ee/scope/impl/EWarFileImpl.java new file mode 100644 index 000000000..306433631 --- /dev/null +++ b/com.ibm.wala.emf/src/com/ibm/wala/ecore/j2ee/scope/impl/EWarFileImpl.java @@ -0,0 +1,44 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.j2ee.scope.impl; + +import com.ibm.wala.ecore.j2ee.scope.EWarFile; +import com.ibm.wala.ecore.j2ee.scope.J2EEScopePackage; + +import com.ibm.wala.ecore.java.scope.impl.EJarFileImpl; + +import org.eclipse.emf.ecore.EClass; + +/** + * + * An implementation of the model object 'EWar File'. + * + *

                              + *

                              + * + * @generated + */ +public class EWarFileImpl extends EJarFileImpl implements EWarFile { + /** + * + * + * @generated + */ + protected EWarFileImpl() { + super(); + } + + /** + * + * + * @generated + */ + protected EClass eStaticClass() { + return J2EEScopePackage.Literals.EWAR_FILE; + } + +} //EWarFileImpl \ No newline at end of file diff --git a/com.ibm.wala.emf/src/com/ibm/wala/ecore/j2ee/scope/impl/J2EEScopeFactoryImpl.java b/com.ibm.wala.emf/src/com/ibm/wala/ecore/j2ee/scope/impl/J2EEScopeFactoryImpl.java new file mode 100644 index 000000000..213e33f70 --- /dev/null +++ b/com.ibm.wala.emf/src/com/ibm/wala/ecore/j2ee/scope/impl/J2EEScopeFactoryImpl.java @@ -0,0 +1,119 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.j2ee.scope.impl; + +import com.ibm.wala.ecore.j2ee.scope.*; + +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EPackage; + +import org.eclipse.emf.ecore.impl.EFactoryImpl; + +import org.eclipse.emf.ecore.plugin.EcorePlugin; + +/** + * + * An implementation of the model Factory. + * + * @generated + */ +public class J2EEScopeFactoryImpl extends EFactoryImpl implements J2EEScopeFactory { + /** + * Creates the default factory implementation. + * + * + * @generated + */ + public static J2EEScopeFactory init() { + try { + J2EEScopeFactory theJ2EEScopeFactory = (J2EEScopeFactory)EPackage.Registry.INSTANCE.getEFactory("http:///com/ibm/wala/wala.ecore.j2ee.scope"); + if (theJ2EEScopeFactory != null) { + return theJ2EEScopeFactory; + } + } + catch (Exception exception) { + EcorePlugin.INSTANCE.log(exception); + } + return new J2EEScopeFactoryImpl(); + } + + /** + * Creates an instance of the factory. + * + * + * @generated + */ + public J2EEScopeFactoryImpl() { + super(); + } + + /** + * + * + * @generated + */ + public EObject create(EClass eClass) { + switch (eClass.getClassifierID()) { + case J2EEScopePackage.EJ2EE_ANALYSIS_SCOPE: return createEJ2EEAnalysisScope(); + case J2EEScopePackage.EEAR_FILE: return createEEarFile(); + case J2EEScopePackage.EWAR_FILE: return createEWarFile(); + default: + throw new IllegalArgumentException("The class '" + eClass.getName() + "' is not a valid classifier"); + } + } + + /** + * + * + * @generated + */ + public EJ2EEAnalysisScope createEJ2EEAnalysisScope() { + EJ2EEAnalysisScopeImpl ej2EEAnalysisScope = new EJ2EEAnalysisScopeImpl(); + return ej2EEAnalysisScope; + } + + /** + * + * + * @generated + */ + public EEarFile createEEarFile() { + EEarFileImpl eEarFile = new EEarFileImpl(); + return eEarFile; + } + + /** + * + * + * @generated + */ + public EWarFile createEWarFile() { + EWarFileImpl eWarFile = new EWarFileImpl(); + return eWarFile; + } + + /** + * + * + * @generated + */ + public J2EEScopePackage getJ2EEScopePackage() { + return (J2EEScopePackage)getEPackage(); + } + + /** + * + * + * @deprecated + * @generated + */ + public static J2EEScopePackage getPackage() { + return J2EEScopePackage.eINSTANCE; + } + +} //J2EEScopeFactoryImpl diff --git a/com.ibm.wala.emf/src/com/ibm/wala/ecore/j2ee/scope/impl/J2EEScopePackageImpl.java b/com.ibm.wala.emf/src/com/ibm/wala/ecore/j2ee/scope/impl/J2EEScopePackageImpl.java new file mode 100644 index 000000000..d88ed1a7d --- /dev/null +++ b/com.ibm.wala.emf/src/com/ibm/wala/ecore/j2ee/scope/impl/J2EEScopePackageImpl.java @@ -0,0 +1,278 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.j2ee.scope.impl; + +import com.ibm.wala.ecore.common.CommonPackage; + +import com.ibm.wala.ecore.common.impl.CommonPackageImpl; + +import com.ibm.wala.ecore.graph.GraphPackage; + +import com.ibm.wala.ecore.graph.impl.GraphPackageImpl; + +import com.ibm.wala.ecore.j2ee.scope.EEarFile; +import com.ibm.wala.ecore.j2ee.scope.EJ2EEAnalysisScope; +import com.ibm.wala.ecore.j2ee.scope.EWarFile; +import com.ibm.wala.ecore.j2ee.scope.J2EEScopeFactory; +import com.ibm.wala.ecore.j2ee.scope.J2EEScopePackage; + +import com.ibm.wala.ecore.java.JavaPackage; + +import com.ibm.wala.ecore.java.callGraph.CallGraphPackage; + +import com.ibm.wala.ecore.java.callGraph.impl.CallGraphPackageImpl; + +import com.ibm.wala.ecore.java.impl.JavaPackageImpl; + +import com.ibm.wala.ecore.java.pointerAnalysis.PointerAnalysisPackage; + +import com.ibm.wala.ecore.java.pointerAnalysis.impl.PointerAnalysisPackageImpl; + +import com.ibm.wala.ecore.java.scope.JavaScopePackage; + +import com.ibm.wala.ecore.java.scope.impl.JavaScopePackageImpl; + +import com.ibm.wala.ecore.perf.PerfPackage; + +import com.ibm.wala.ecore.perf.impl.PerfPackageImpl; + +import com.ibm.wala.ecore.regex.RegexPackage; + +import com.ibm.wala.ecore.regex.impl.RegexPackageImpl; + +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EPackage; + +import org.eclipse.emf.ecore.impl.EPackageImpl; + +/** + * + * An implementation of the model Package. + * + * @generated + */ +public class J2EEScopePackageImpl extends EPackageImpl implements J2EEScopePackage { + /** + * + * + * @generated + */ + private EClass ej2EEAnalysisScopeEClass = null; + + /** + * + * + * @generated + */ + private EClass eEarFileEClass = null; + + /** + * + * + * @generated + */ + private EClass eWarFileEClass = null; + + /** + * Creates an instance of the model Package, registered with + * {@link org.eclipse.emf.ecore.EPackage.Registry EPackage.Registry} by the package + * package URI value. + *

                              Note: the correct way to create the package is via the static + * factory method {@link #init init()}, which also performs + * initialization of the package, or returns the registered package, + * if one already exists. + * + * + * @see org.eclipse.emf.ecore.EPackage.Registry + * @see com.ibm.wala.ecore.j2ee.scope.J2EEScopePackage#eNS_URI + * @see #init() + * @generated + */ + private J2EEScopePackageImpl() { + super(eNS_URI, J2EEScopeFactory.eINSTANCE); + } + + /** + * + * + * @generated + */ + private static boolean isInited = false; + + /** + * Creates, registers, and initializes the Package for this + * model, and for any others upon which it depends. Simple + * dependencies are satisfied by calling this method on all + * dependent packages before doing anything else. This method drives + * initialization for interdependent packages directly, in parallel + * with this package, itself. + *

                              Of this package and its interdependencies, all packages which + * have not yet been registered by their URI values are first created + * and registered. The packages are then initialized in two steps: + * meta-model objects for all of the packages are created before any + * are initialized, since one package's meta-model objects may refer to + * those of another. + *

                              Invocation of this method will not affect any packages that have + * already been initialized. + * + * + * @see #eNS_URI + * @see #createPackageContents() + * @see #initializePackageContents() + * @generated + */ + public static J2EEScopePackage init() { + if (isInited) return (J2EEScopePackage)EPackage.Registry.INSTANCE.getEPackage(J2EEScopePackage.eNS_URI); + + // Obtain or create and register package + J2EEScopePackageImpl theJ2EEScopePackage = (J2EEScopePackageImpl)(EPackage.Registry.INSTANCE.getEPackage(eNS_URI) instanceof J2EEScopePackageImpl ? EPackage.Registry.INSTANCE.getEPackage(eNS_URI) : new J2EEScopePackageImpl()); + + isInited = true; + + // Obtain or create and register interdependencies + GraphPackageImpl theGraphPackage = (GraphPackageImpl)(EPackage.Registry.INSTANCE.getEPackage(GraphPackage.eNS_URI) instanceof GraphPackageImpl ? EPackage.Registry.INSTANCE.getEPackage(GraphPackage.eNS_URI) : GraphPackage.eINSTANCE); + CommonPackageImpl theCommonPackage = (CommonPackageImpl)(EPackage.Registry.INSTANCE.getEPackage(CommonPackage.eNS_URI) instanceof CommonPackageImpl ? EPackage.Registry.INSTANCE.getEPackage(CommonPackage.eNS_URI) : CommonPackage.eINSTANCE); + RegexPackageImpl theRegexPackage = (RegexPackageImpl)(EPackage.Registry.INSTANCE.getEPackage(RegexPackage.eNS_URI) instanceof RegexPackageImpl ? EPackage.Registry.INSTANCE.getEPackage(RegexPackage.eNS_URI) : RegexPackage.eINSTANCE); + PerfPackageImpl thePerfPackage = (PerfPackageImpl)(EPackage.Registry.INSTANCE.getEPackage(PerfPackage.eNS_URI) instanceof PerfPackageImpl ? EPackage.Registry.INSTANCE.getEPackage(PerfPackage.eNS_URI) : PerfPackage.eINSTANCE); + JavaPackageImpl theJavaPackage = (JavaPackageImpl)(EPackage.Registry.INSTANCE.getEPackage(JavaPackage.eNS_URI) instanceof JavaPackageImpl ? EPackage.Registry.INSTANCE.getEPackage(JavaPackage.eNS_URI) : JavaPackage.eINSTANCE); + CallGraphPackageImpl theCallGraphPackage = (CallGraphPackageImpl)(EPackage.Registry.INSTANCE.getEPackage(CallGraphPackage.eNS_URI) instanceof CallGraphPackageImpl ? EPackage.Registry.INSTANCE.getEPackage(CallGraphPackage.eNS_URI) : CallGraphPackage.eINSTANCE); + PointerAnalysisPackageImpl thePointerAnalysisPackage = (PointerAnalysisPackageImpl)(EPackage.Registry.INSTANCE.getEPackage(PointerAnalysisPackage.eNS_URI) instanceof PointerAnalysisPackageImpl ? EPackage.Registry.INSTANCE.getEPackage(PointerAnalysisPackage.eNS_URI) : PointerAnalysisPackage.eINSTANCE); + JavaScopePackageImpl theJavaScopePackage = (JavaScopePackageImpl)(EPackage.Registry.INSTANCE.getEPackage(JavaScopePackage.eNS_URI) instanceof JavaScopePackageImpl ? EPackage.Registry.INSTANCE.getEPackage(JavaScopePackage.eNS_URI) : JavaScopePackage.eINSTANCE); + + // Create package meta-data objects + theJ2EEScopePackage.createPackageContents(); + theGraphPackage.createPackageContents(); + theCommonPackage.createPackageContents(); + theRegexPackage.createPackageContents(); + thePerfPackage.createPackageContents(); + theJavaPackage.createPackageContents(); + theCallGraphPackage.createPackageContents(); + thePointerAnalysisPackage.createPackageContents(); + theJavaScopePackage.createPackageContents(); + + // Initialize created meta-data + theJ2EEScopePackage.initializePackageContents(); + theGraphPackage.initializePackageContents(); + theCommonPackage.initializePackageContents(); + theRegexPackage.initializePackageContents(); + thePerfPackage.initializePackageContents(); + theJavaPackage.initializePackageContents(); + theCallGraphPackage.initializePackageContents(); + thePointerAnalysisPackage.initializePackageContents(); + theJavaScopePackage.initializePackageContents(); + + // Mark meta-data to indicate it can't be changed + theJ2EEScopePackage.freeze(); + + return theJ2EEScopePackage; + } + + /** + * + * + * @generated + */ + public EClass getEJ2EEAnalysisScope() { + return ej2EEAnalysisScopeEClass; + } + + /** + * + * + * @generated + */ + public EClass getEEarFile() { + return eEarFileEClass; + } + + /** + * + * + * @generated + */ + public EClass getEWarFile() { + return eWarFileEClass; + } + + /** + * + * + * @generated + */ + public J2EEScopeFactory getJ2EEScopeFactory() { + return (J2EEScopeFactory)getEFactoryInstance(); + } + + /** + * + * + * @generated + */ + private boolean isCreated = false; + + /** + * Creates the meta-model objects for the package. This method is + * guarded to have no affect on any invocation but its first. + * + * + * @generated + */ + public void createPackageContents() { + if (isCreated) return; + isCreated = true; + + // Create classes and their features + ej2EEAnalysisScopeEClass = createEClass(EJ2EE_ANALYSIS_SCOPE); + + eEarFileEClass = createEClass(EEAR_FILE); + + eWarFileEClass = createEClass(EWAR_FILE); + } + + /** + * + * + * @generated + */ + private boolean isInitialized = false; + + /** + * Complete the initialization of the package and its meta-model. This + * method is guarded to have no affect on any invocation but its first. + * + * + * @generated + */ + public void initializePackageContents() { + if (isInitialized) return; + isInitialized = true; + + // Initialize package + setName(eNAME); + setNsPrefix(eNS_PREFIX); + setNsURI(eNS_URI); + + // Obtain other dependent packages + JavaScopePackage theJavaScopePackage = (JavaScopePackage)EPackage.Registry.INSTANCE.getEPackage(JavaScopePackage.eNS_URI); + + // Add supertypes to classes + ej2EEAnalysisScopeEClass.getESuperTypes().add(theJavaScopePackage.getEJavaAnalysisScope()); + eEarFileEClass.getESuperTypes().add(theJavaScopePackage.getEJarFile()); + eWarFileEClass.getESuperTypes().add(theJavaScopePackage.getEJarFile()); + + // Initialize classes and features; add operations and parameters + initEClass(ej2EEAnalysisScopeEClass, EJ2EEAnalysisScope.class, "EJ2EEAnalysisScope", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); + + initEClass(eEarFileEClass, EEarFile.class, "EEarFile", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); + + initEClass(eWarFileEClass, EWarFile.class, "EWarFile", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); + + // Create resource + createResource(eNS_URI); + } + +} //J2EEScopePackageImpl diff --git a/com.ibm.wala.emf/src/com/ibm/wala/ecore/j2ee/scope/util/J2EEScopeAdapterFactory.java b/com.ibm.wala.emf/src/com/ibm/wala/ecore/j2ee/scope/util/J2EEScopeAdapterFactory.java new file mode 100644 index 000000000..1f750aadd --- /dev/null +++ b/com.ibm.wala.emf/src/com/ibm/wala/ecore/j2ee/scope/util/J2EEScopeAdapterFactory.java @@ -0,0 +1,209 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.j2ee.scope.util; + +import com.ibm.wala.ecore.j2ee.scope.*; + +import com.ibm.wala.ecore.java.scope.EJarFile; +import com.ibm.wala.ecore.java.scope.EJavaAnalysisScope; +import com.ibm.wala.ecore.java.scope.EModule; + +import org.eclipse.emf.common.notify.Adapter; +import org.eclipse.emf.common.notify.Notifier; + +import org.eclipse.emf.common.notify.impl.AdapterFactoryImpl; + +import org.eclipse.emf.ecore.EObject; + +/** + * + * The Adapter Factory for the model. + * It provides an adapter createXXX method for each class of the model. + * + * @see com.ibm.wala.ecore.j2ee.scope.J2EEScopePackage + * @generated + */ +public class J2EEScopeAdapterFactory extends AdapterFactoryImpl { + /** + * The cached model package. + * + * + * @generated + */ + protected static J2EEScopePackage modelPackage; + + /** + * Creates an instance of the adapter factory. + * + * + * @generated + */ + public J2EEScopeAdapterFactory() { + if (modelPackage == null) { + modelPackage = J2EEScopePackage.eINSTANCE; + } + } + + /** + * Returns whether this factory is applicable for the type of the object. + * + * This implementation returns true if the object is either the model's package or is an instance object of the model. + * + * @return whether this factory is applicable for the type of the object. + * @generated + */ + public boolean isFactoryForType(Object object) { + if (object == modelPackage) { + return true; + } + if (object instanceof EObject) { + return ((EObject)object).eClass().getEPackage() == modelPackage; + } + return false; + } + + /** + * The switch the delegates to the createXXX methods. + * + * + * @generated + */ + protected J2EEScopeSwitch modelSwitch = + new J2EEScopeSwitch() { + public Object caseEJ2EEAnalysisScope(EJ2EEAnalysisScope object) { + return createEJ2EEAnalysisScopeAdapter(); + } + public Object caseEEarFile(EEarFile object) { + return createEEarFileAdapter(); + } + public Object caseEWarFile(EWarFile object) { + return createEWarFileAdapter(); + } + public Object caseEJavaAnalysisScope(EJavaAnalysisScope object) { + return createEJavaAnalysisScopeAdapter(); + } + public Object caseEModule(EModule object) { + return createEModuleAdapter(); + } + public Object caseEJarFile(EJarFile object) { + return createEJarFileAdapter(); + } + public Object defaultCase(EObject object) { + return createEObjectAdapter(); + } + }; + + /** + * Creates an adapter for the target. + * + * + * @param target the object to adapt. + * @return the adapter for the target. + * @generated + */ + public Adapter createAdapter(Notifier target) { + return (Adapter)modelSwitch.doSwitch((EObject)target); + } + + + /** + * Creates a new adapter for an object of class '{@link com.ibm.wala.ecore.j2ee.scope.EJ2EEAnalysisScope EJ2EE Analysis Scope}'. + * + * This default implementation returns null so that we can easily ignore cases; + * it's useful to ignore a case when inheritance will catch all the cases anyway. + * + * @return the new adapter. + * @see com.ibm.wala.ecore.j2ee.scope.EJ2EEAnalysisScope + * @generated + */ + public Adapter createEJ2EEAnalysisScopeAdapter() { + return null; + } + + /** + * Creates a new adapter for an object of class '{@link com.ibm.wala.ecore.j2ee.scope.EEarFile EEar File}'. + * + * This default implementation returns null so that we can easily ignore cases; + * it's useful to ignore a case when inheritance will catch all the cases anyway. + * + * @return the new adapter. + * @see com.ibm.wala.ecore.j2ee.scope.EEarFile + * @generated + */ + public Adapter createEEarFileAdapter() { + return null; + } + + /** + * Creates a new adapter for an object of class '{@link com.ibm.wala.ecore.j2ee.scope.EWarFile EWar File}'. + * + * This default implementation returns null so that we can easily ignore cases; + * it's useful to ignore a case when inheritance will catch all the cases anyway. + * + * @return the new adapter. + * @see com.ibm.wala.ecore.j2ee.scope.EWarFile + * @generated + */ + public Adapter createEWarFileAdapter() { + return null; + } + + /** + * Creates a new adapter for an object of class '{@link com.ibm.wala.ecore.java.scope.EJavaAnalysisScope EJava Analysis Scope}'. + * + * This default implementation returns null so that we can easily ignore cases; + * it's useful to ignore a case when inheritance will catch all the cases anyway. + * + * @return the new adapter. + * @see com.ibm.wala.ecore.java.scope.EJavaAnalysisScope + * @generated + */ + public Adapter createEJavaAnalysisScopeAdapter() { + return null; + } + + /** + * Creates a new adapter for an object of class '{@link com.ibm.wala.ecore.java.scope.EModule EModule}'. + * + * This default implementation returns null so that we can easily ignore cases; + * it's useful to ignore a case when inheritance will catch all the cases anyway. + * + * @return the new adapter. + * @see com.ibm.wala.ecore.java.scope.EModule + * @generated + */ + public Adapter createEModuleAdapter() { + return null; + } + + /** + * Creates a new adapter for an object of class '{@link com.ibm.wala.ecore.java.scope.EJarFile EJar File}'. + * + * This default implementation returns null so that we can easily ignore cases; + * it's useful to ignore a case when inheritance will catch all the cases anyway. + * + * @return the new adapter. + * @see com.ibm.wala.ecore.java.scope.EJarFile + * @generated + */ + public Adapter createEJarFileAdapter() { + return null; + } + + /** + * Creates a new adapter for the default case. + * + * This default implementation returns null. + * + * @return the new adapter. + * @generated + */ + public Adapter createEObjectAdapter() { + return null; + } + +} //J2EEScopeAdapterFactory diff --git a/com.ibm.wala.emf/src/com/ibm/wala/ecore/j2ee/scope/util/J2EEScopeSwitch.java b/com.ibm.wala.emf/src/com/ibm/wala/ecore/j2ee/scope/util/J2EEScopeSwitch.java new file mode 100644 index 000000000..7877b9c37 --- /dev/null +++ b/com.ibm.wala.emf/src/com/ibm/wala/ecore/j2ee/scope/util/J2EEScopeSwitch.java @@ -0,0 +1,226 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.j2ee.scope.util; + +import com.ibm.wala.ecore.j2ee.scope.*; + +import com.ibm.wala.ecore.java.scope.EJarFile; +import com.ibm.wala.ecore.java.scope.EJavaAnalysisScope; +import com.ibm.wala.ecore.java.scope.EModule; + +import java.util.List; + +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EObject; + +/** + * + * The Switch for the model's inheritance hierarchy. + * It supports the call {@link #doSwitch(EObject) doSwitch(object)} + * to invoke the caseXXX method for each class of the model, + * starting with the actual class of the object + * and proceeding up the inheritance hierarchy + * until a non-null result is returned, + * which is the result of the switch. + * + * @see com.ibm.wala.ecore.j2ee.scope.J2EEScopePackage + * @generated + */ +public class J2EEScopeSwitch { + /** + * The cached model package + * + * + * @generated + */ + protected static J2EEScopePackage modelPackage; + + /** + * Creates an instance of the switch. + * + * + * @generated + */ + public J2EEScopeSwitch() { + if (modelPackage == null) { + modelPackage = J2EEScopePackage.eINSTANCE; + } + } + + /** + * Calls caseXXX for each class of the model until one returns a non null result; it yields that result. + * + * + * @return the first non-null result returned by a caseXXX call. + * @generated + */ + public Object doSwitch(EObject theEObject) { + return doSwitch(theEObject.eClass(), theEObject); + } + + /** + * Calls caseXXX for each class of the model until one returns a non null result; it yields that result. + * + * + * @return the first non-null result returned by a caseXXX call. + * @generated + */ + protected Object doSwitch(EClass theEClass, EObject theEObject) { + if (theEClass.eContainer() == modelPackage) { + return doSwitch(theEClass.getClassifierID(), theEObject); + } + else { + List eSuperTypes = theEClass.getESuperTypes(); + return + eSuperTypes.isEmpty() ? + defaultCase(theEObject) : + doSwitch((EClass)eSuperTypes.get(0), theEObject); + } + } + + /** + * Calls caseXXX for each class of the model until one returns a non null result; it yields that result. + * + * + * @return the first non-null result returned by a caseXXX call. + * @generated + */ + protected Object doSwitch(int classifierID, EObject theEObject) { + switch (classifierID) { + case J2EEScopePackage.EJ2EE_ANALYSIS_SCOPE: { + EJ2EEAnalysisScope ej2EEAnalysisScope = (EJ2EEAnalysisScope)theEObject; + Object result = caseEJ2EEAnalysisScope(ej2EEAnalysisScope); + if (result == null) result = caseEJavaAnalysisScope(ej2EEAnalysisScope); + if (result == null) result = defaultCase(theEObject); + return result; + } + case J2EEScopePackage.EEAR_FILE: { + EEarFile eEarFile = (EEarFile)theEObject; + Object result = caseEEarFile(eEarFile); + if (result == null) result = caseEJarFile(eEarFile); + if (result == null) result = caseEModule(eEarFile); + if (result == null) result = defaultCase(theEObject); + return result; + } + case J2EEScopePackage.EWAR_FILE: { + EWarFile eWarFile = (EWarFile)theEObject; + Object result = caseEWarFile(eWarFile); + if (result == null) result = caseEJarFile(eWarFile); + if (result == null) result = caseEModule(eWarFile); + if (result == null) result = defaultCase(theEObject); + return result; + } + default: return defaultCase(theEObject); + } + } + + /** + * Returns the result of interpretting the object as an instance of 'EJ2EE Analysis Scope'. + * + * This implementation returns null; + * returning a non-null result will terminate the switch. + * + * @param object the target of the switch. + * @return the result of interpretting the object as an instance of 'EJ2EE Analysis Scope'. + * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject) + * @generated + */ + public Object caseEJ2EEAnalysisScope(EJ2EEAnalysisScope object) { + return null; + } + + /** + * Returns the result of interpretting the object as an instance of 'EEar File'. + * + * This implementation returns null; + * returning a non-null result will terminate the switch. + * + * @param object the target of the switch. + * @return the result of interpretting the object as an instance of 'EEar File'. + * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject) + * @generated + */ + public Object caseEEarFile(EEarFile object) { + return null; + } + + /** + * Returns the result of interpretting the object as an instance of 'EWar File'. + * + * This implementation returns null; + * returning a non-null result will terminate the switch. + * + * @param object the target of the switch. + * @return the result of interpretting the object as an instance of 'EWar File'. + * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject) + * @generated + */ + public Object caseEWarFile(EWarFile object) { + return null; + } + + /** + * Returns the result of interpretting the object as an instance of 'EJava Analysis Scope'. + * + * This implementation returns null; + * returning a non-null result will terminate the switch. + * + * @param object the target of the switch. + * @return the result of interpretting the object as an instance of 'EJava Analysis Scope'. + * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject) + * @generated + */ + public Object caseEJavaAnalysisScope(EJavaAnalysisScope object) { + return null; + } + + /** + * Returns the result of interpretting the object as an instance of 'EModule'. + * + * This implementation returns null; + * returning a non-null result will terminate the switch. + * + * @param object the target of the switch. + * @return the result of interpretting the object as an instance of 'EModule'. + * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject) + * @generated + */ + public Object caseEModule(EModule object) { + return null; + } + + /** + * Returns the result of interpretting the object as an instance of 'EJar File'. + * + * This implementation returns null; + * returning a non-null result will terminate the switch. + * + * @param object the target of the switch. + * @return the result of interpretting the object as an instance of 'EJar File'. + * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject) + * @generated + */ + public Object caseEJarFile(EJarFile object) { + return null; + } + + /** + * Returns the result of interpretting the object as an instance of 'EObject'. + * + * This implementation returns null; + * returning a non-null result will terminate the switch, but this is the last case anyway. + * + * @param object the target of the switch. + * @return the result of interpretting the object as an instance of 'EObject'. + * @see #doSwitch(org.eclipse.emf.ecore.EObject) + * @generated + */ + public Object defaultCase(EObject object) { + return null; + } + +} //J2EEScopeSwitch diff --git a/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/ECallSite.java b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/ECallSite.java new file mode 100644 index 000000000..08404e30f --- /dev/null +++ b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/ECallSite.java @@ -0,0 +1,108 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java; + +import com.ibm.wala.ecore.common.EObjectWithContainerId; + +/** + * + * A representation of the model object 'ECall Site'. + * + * + *

                              + * The following features are supported: + *

                                + *
                              • {@link com.ibm.wala.ecore.java.ECallSite#getBytecodeIndex Bytecode Index}
                              • + *
                              • {@link com.ibm.wala.ecore.java.ECallSite#getJavaMethod Java Method}
                              • + *
                              • {@link com.ibm.wala.ecore.java.ECallSite#getDeclaredTarget Declared Target}
                              • + *
                              + *

                              + * + * @see com.ibm.wala.ecore.java.JavaPackage#getECallSite() + * @model + * @generated + */ +public interface ECallSite extends EObjectWithContainerId { + /** + * Returns the value of the 'Bytecode Index' attribute. + * + *

                              + * If the meaning of the 'Bytecode Index' attribute isn't clear, + * there really should be more of a description here... + *

                              + * + * @return the value of the 'Bytecode Index' attribute. + * @see #setBytecodeIndex(int) + * @see com.ibm.wala.ecore.java.JavaPackage#getECallSite_BytecodeIndex() + * @model + * @generated + */ + int getBytecodeIndex(); + + /** + * Sets the value of the '{@link com.ibm.wala.ecore.java.ECallSite#getBytecodeIndex Bytecode Index}' attribute. + * + * + * @param value the new value of the 'Bytecode Index' attribute. + * @see #getBytecodeIndex() + * @generated + */ + void setBytecodeIndex(int value); + + /** + * Returns the value of the 'Java Method' reference. + * + *

                              + * If the meaning of the 'Java Method' reference isn't clear, + * there really should be more of a description here... + *

                              + * + * @return the value of the 'Java Method' reference. + * @see #setJavaMethod(EJavaMethod) + * @see com.ibm.wala.ecore.java.JavaPackage#getECallSite_JavaMethod() + * @model required="true" + * @generated + */ + EJavaMethod getJavaMethod(); + + /** + * Sets the value of the '{@link com.ibm.wala.ecore.java.ECallSite#getJavaMethod Java Method}' reference. + * + * + * @param value the new value of the 'Java Method' reference. + * @see #getJavaMethod() + * @generated + */ + void setJavaMethod(EJavaMethod value); + + /** + * Returns the value of the 'Declared Target' reference. + * + *

                              + * If the meaning of the 'Declared Target' reference isn't clear, + * there really should be more of a description here... + *

                              + * + * @return the value of the 'Declared Target' reference. + * @see #setDeclaredTarget(EJavaMethod) + * @see com.ibm.wala.ecore.java.JavaPackage#getECallSite_DeclaredTarget() + * @model required="true" + * @generated + */ + EJavaMethod getDeclaredTarget(); + + /** + * Sets the value of the '{@link com.ibm.wala.ecore.java.ECallSite#getDeclaredTarget Declared Target}' reference. + * + * + * @param value the new value of the 'Declared Target' reference. + * @see #getDeclaredTarget() + * @generated + */ + void setDeclaredTarget(EJavaMethod value); + +} // ECallSite \ No newline at end of file diff --git a/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/EClassHierarchy.java b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/EClassHierarchy.java new file mode 100644 index 000000000..f1287fae6 --- /dev/null +++ b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/EClassHierarchy.java @@ -0,0 +1,22 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java; + +import com.ibm.wala.ecore.graph.ETree; + +/** + * + * A representation of the model object 'EClass Hierarchy'. + * + * + * + * @see com.ibm.wala.ecore.java.JavaPackage#getEClassHierarchy() + * @model + * @generated + */ +public interface EClassHierarchy extends ETree { +} // EClassHierarchy \ No newline at end of file diff --git a/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/EClassLoaderName.java b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/EClassLoaderName.java new file mode 100644 index 000000000..e92357df0 --- /dev/null +++ b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/EClassLoaderName.java @@ -0,0 +1,178 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import org.eclipse.emf.common.util.AbstractEnumerator; + +/** + * + * A representation of the literals of the enumeration 'EClass Loader Name', + * and utility methods for working with them. + * + * @see com.ibm.wala.ecore.java.JavaPackage#getEClassLoaderName() + * @model + * @generated + */ +public final class EClassLoaderName extends AbstractEnumerator { + /** + * The 'Application' literal value. + * + *

                              + * If the meaning of 'Application' literal object isn't clear, + * there really should be more of a description here... + *

                              + * + * @see #APPLICATION_LITERAL + * @model name="Application" + * @generated + * @ordered + */ + public static final int APPLICATION = 0; + + /** + * The 'Primordial' literal value. + * + *

                              + * If the meaning of 'Primordial' literal object isn't clear, + * there really should be more of a description here... + *

                              + * + * @see #PRIMORDIAL_LITERAL + * @model name="Primordial" + * @generated + * @ordered + */ + public static final int PRIMORDIAL = 1; + + /** + * The 'Extension' literal value. + * + *

                              + * If the meaning of 'Extension' literal object isn't clear, + * there really should be more of a description here... + *

                              + * + * @see #EXTENSION_LITERAL + * @model name="Extension" + * @generated + * @ordered + */ + public static final int EXTENSION = 2; + + /** + * The 'Application' literal object. + * + * + * @see #APPLICATION + * @generated + * @ordered + */ + public static final EClassLoaderName APPLICATION_LITERAL = new EClassLoaderName(APPLICATION, "Application", "Application"); + + /** + * The 'Primordial' literal object. + * + * + * @see #PRIMORDIAL + * @generated + * @ordered + */ + public static final EClassLoaderName PRIMORDIAL_LITERAL = new EClassLoaderName(PRIMORDIAL, "Primordial", "Primordial"); + + /** + * The 'Extension' literal object. + * + * + * @see #EXTENSION + * @generated + * @ordered + */ + public static final EClassLoaderName EXTENSION_LITERAL = new EClassLoaderName(EXTENSION, "Extension", "Extension"); + + /** + * An array of all the 'EClass Loader Name' enumerators. + * + * + * @generated + */ + private static final EClassLoaderName[] VALUES_ARRAY = + new EClassLoaderName[] { + APPLICATION_LITERAL, + PRIMORDIAL_LITERAL, + EXTENSION_LITERAL, + }; + + /** + * A public read-only list of all the 'EClass Loader Name' enumerators. + * + * + * @generated + */ + public static final List VALUES = Collections.unmodifiableList(Arrays.asList(VALUES_ARRAY)); + + /** + * Returns the 'EClass Loader Name' literal with the specified literal value. + * + * + * @generated + */ + public static EClassLoaderName get(String literal) { + for (int i = 0; i < VALUES_ARRAY.length; ++i) { + EClassLoaderName result = VALUES_ARRAY[i]; + if (result.toString().equals(literal)) { + return result; + } + } + return null; + } + + /** + * Returns the 'EClass Loader Name' literal with the specified name. + * + * + * @generated + */ + public static EClassLoaderName getByName(String name) { + for (int i = 0; i < VALUES_ARRAY.length; ++i) { + EClassLoaderName result = VALUES_ARRAY[i]; + if (result.getName().equals(name)) { + return result; + } + } + return null; + } + + /** + * Returns the 'EClass Loader Name' literal with the specified integer value. + * + * + * @generated + */ + public static EClassLoaderName get(int value) { + switch (value) { + case APPLICATION: return APPLICATION_LITERAL; + case PRIMORDIAL: return PRIMORDIAL_LITERAL; + case EXTENSION: return EXTENSION_LITERAL; + } + return null; + } + + /** + * Only this class can construct instances. + * + * + * @generated + */ + private EClassLoaderName(int value, String name, String literal) { + super(value, name, literal); + } + +} //EClassLoaderName diff --git a/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/EInterfaceHierarchy.java b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/EInterfaceHierarchy.java new file mode 100644 index 000000000..9ec5422e0 --- /dev/null +++ b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/EInterfaceHierarchy.java @@ -0,0 +1,22 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java; + +import com.ibm.wala.ecore.graph.EGraph; + +/** + * + * A representation of the model object 'EInterface Hierarchy'. + * + * + * + * @see com.ibm.wala.ecore.java.JavaPackage#getEInterfaceHierarchy() + * @model + * @generated + */ +public interface EInterfaceHierarchy extends EGraph { +} // EInterfaceHierarchy \ No newline at end of file diff --git a/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/EJavaClass.java b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/EJavaClass.java new file mode 100644 index 000000000..85271b0a2 --- /dev/null +++ b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/EJavaClass.java @@ -0,0 +1,84 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java; + +import com.ibm.wala.ecore.common.EObjectWithContainerId; + +/** + * + * A representation of the model object 'EJava Class'. + * + * + *

                              + * The following features are supported: + *

                                + *
                              • {@link com.ibm.wala.ecore.java.EJavaClass#getClassName Class Name}
                              • + *
                              • {@link com.ibm.wala.ecore.java.EJavaClass#getLoader Loader}
                              • + *
                              + *

                              + * + * @see com.ibm.wala.ecore.java.JavaPackage#getEJavaClass() + * @model + * @generated + */ +public interface EJavaClass extends EObjectWithContainerId { + /** + * Returns the value of the 'Class Name' attribute. + * + *

                              + * If the meaning of the 'Class Name' attribute isn't clear, + * there really should be more of a description here... + *

                              + * + * @return the value of the 'Class Name' attribute. + * @see #setClassName(String) + * @see com.ibm.wala.ecore.java.JavaPackage#getEJavaClass_ClassName() + * @model required="true" + * @generated + */ + String getClassName(); + + /** + * Sets the value of the '{@link com.ibm.wala.ecore.java.EJavaClass#getClassName Class Name}' attribute. + * + * + * @param value the new value of the 'Class Name' attribute. + * @see #getClassName() + * @generated + */ + void setClassName(String value); + + /** + * Returns the value of the 'Loader' attribute. + * The literals are from the enumeration {@link com.ibm.wala.ecore.java.EClassLoaderName}. + * + *

                              + * If the meaning of the 'Loader' attribute isn't clear, + * there really should be more of a description here... + *

                              + * + * @return the value of the 'Loader' attribute. + * @see com.ibm.wala.ecore.java.EClassLoaderName + * @see #setLoader(EClassLoaderName) + * @see com.ibm.wala.ecore.java.JavaPackage#getEJavaClass_Loader() + * @model required="true" + * @generated + */ + EClassLoaderName getLoader(); + + /** + * Sets the value of the '{@link com.ibm.wala.ecore.java.EJavaClass#getLoader Loader}' attribute. + * + * + * @param value the new value of the 'Loader' attribute. + * @see com.ibm.wala.ecore.java.EClassLoaderName + * @see #getLoader() + * @generated + */ + void setLoader(EClassLoaderName value); + +} // EJavaClass \ No newline at end of file diff --git a/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/EJavaMethod.java b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/EJavaMethod.java new file mode 100644 index 000000000..1ba78d46b --- /dev/null +++ b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/EJavaMethod.java @@ -0,0 +1,132 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java; + +import com.ibm.wala.ecore.common.EObjectWithContainerId; + +/** + * + * A representation of the model object 'EJava Method'. + * + * + *

                              + * The following features are supported: + *

                                + *
                              • {@link com.ibm.wala.ecore.java.EJavaMethod#getMethodName Method Name}
                              • + *
                              • {@link com.ibm.wala.ecore.java.EJavaMethod#getDescriptor Descriptor}
                              • + *
                              • {@link com.ibm.wala.ecore.java.EJavaMethod#getJavaClass Java Class}
                              • + *
                              • {@link com.ibm.wala.ecore.java.EJavaMethod#getSignature Signature}
                              • + *
                              + *

                              + * + * @see com.ibm.wala.ecore.java.JavaPackage#getEJavaMethod() + * @model + * @generated + */ +public interface EJavaMethod extends EObjectWithContainerId { + /** + * Returns the value of the 'Method Name' attribute. + * + *

                              + * If the meaning of the 'Method Name' attribute isn't clear, + * there really should be more of a description here... + *

                              + * + * @return the value of the 'Method Name' attribute. + * @see #setMethodName(String) + * @see com.ibm.wala.ecore.java.JavaPackage#getEJavaMethod_MethodName() + * @model required="true" + * @generated + */ + String getMethodName(); + + /** + * Sets the value of the '{@link com.ibm.wala.ecore.java.EJavaMethod#getMethodName Method Name}' attribute. + * + * + * @param value the new value of the 'Method Name' attribute. + * @see #getMethodName() + * @generated + */ + void setMethodName(String value); + + /** + * Returns the value of the 'Descriptor' attribute. + * + *

                              + * If the meaning of the 'Descriptor' attribute isn't clear, + * there really should be more of a description here... + *

                              + * + * @return the value of the 'Descriptor' attribute. + * @see #setDescriptor(String) + * @see com.ibm.wala.ecore.java.JavaPackage#getEJavaMethod_Descriptor() + * @model required="true" + * @generated + */ + String getDescriptor(); + + /** + * Sets the value of the '{@link com.ibm.wala.ecore.java.EJavaMethod#getDescriptor Descriptor}' attribute. + * + * + * @param value the new value of the 'Descriptor' attribute. + * @see #getDescriptor() + * @generated + */ + void setDescriptor(String value); + + /** + * Returns the value of the 'Java Class' reference. + * + *

                              + * If the meaning of the 'Java Class' reference isn't clear, + * there really should be more of a description here... + *

                              + * + * @return the value of the 'Java Class' reference. + * @see #setJavaClass(EJavaClass) + * @see com.ibm.wala.ecore.java.JavaPackage#getEJavaMethod_JavaClass() + * @model required="true" + * @generated + */ + EJavaClass getJavaClass(); + + /** + * Sets the value of the '{@link com.ibm.wala.ecore.java.EJavaMethod#getJavaClass Java Class}' reference. + * + * + * @param value the new value of the 'Java Class' reference. + * @see #getJavaClass() + * @generated + */ + void setJavaClass(EJavaClass value); + + /** + * Returns the value of the 'Signature' attribute. + * + *

                              + * If the meaning of the 'Signature' attribute isn't clear, + * there really should be more of a description here... + *

                              + * + * @return the value of the 'Signature' attribute. + * @see com.ibm.wala.ecore.java.JavaPackage#getEJavaMethod_Signature() + * @model transient="true" changeable="false" volatile="true" derived="true" + * @generated + */ + String getSignature(); + + /** + * + * + * @model kind="operation" ordered="false" + * @generated + */ + boolean isClinit(); + +} // EJavaMethod \ No newline at end of file diff --git a/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/ETypeHierarchy.java b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/ETypeHierarchy.java new file mode 100644 index 000000000..bf29884af --- /dev/null +++ b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/ETypeHierarchy.java @@ -0,0 +1,110 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java; + +import com.ibm.wala.ecore.common.ERelation; + +import org.eclipse.emf.ecore.EObject; + +/** + * + * A representation of the model object 'EType Hierarchy'. + * + * + *

                              + * The following features are supported: + *

                                + *
                              • {@link com.ibm.wala.ecore.java.ETypeHierarchy#getClasses Classes}
                              • + *
                              • {@link com.ibm.wala.ecore.java.ETypeHierarchy#getInterfaces Interfaces}
                              • + *
                              • {@link com.ibm.wala.ecore.java.ETypeHierarchy#getImplements Implements}
                              • + *
                              + *

                              + * + * @see com.ibm.wala.ecore.java.JavaPackage#getETypeHierarchy() + * @model + * @generated + */ +public interface ETypeHierarchy extends EObject { + /** + * Returns the value of the 'Classes' containment reference. + * + *

                              + * If the meaning of the 'Classes' containment reference isn't clear, + * there really should be more of a description here... + *

                              + * + * @return the value of the 'Classes' containment reference. + * @see #setClasses(EClassHierarchy) + * @see com.ibm.wala.ecore.java.JavaPackage#getETypeHierarchy_Classes() + * @model containment="true" required="true" + * @generated + */ + EClassHierarchy getClasses(); + + /** + * Sets the value of the '{@link com.ibm.wala.ecore.java.ETypeHierarchy#getClasses Classes}' containment reference. + * + * + * @param value the new value of the 'Classes' containment reference. + * @see #getClasses() + * @generated + */ + void setClasses(EClassHierarchy value); + + /** + * Returns the value of the 'Interfaces' containment reference. + * + *

                              + * If the meaning of the 'Interfaces' containment reference isn't clear, + * there really should be more of a description here... + *

                              + * + * @return the value of the 'Interfaces' containment reference. + * @see #setInterfaces(EInterfaceHierarchy) + * @see com.ibm.wala.ecore.java.JavaPackage#getETypeHierarchy_Interfaces() + * @model containment="true" required="true" + * @generated + */ + EInterfaceHierarchy getInterfaces(); + + /** + * Sets the value of the '{@link com.ibm.wala.ecore.java.ETypeHierarchy#getInterfaces Interfaces}' containment reference. + * + * + * @param value the new value of the 'Interfaces' containment reference. + * @see #getInterfaces() + * @generated + */ + void setInterfaces(EInterfaceHierarchy value); + + /** + * Returns the value of the 'Implements' containment reference. + * + *

                              + * If the meaning of the 'Implements' containment reference isn't clear, + * there really should be more of a description here... + *

                              + * + * @return the value of the 'Implements' containment reference. + * @see #setImplements(ERelation) + * @see com.ibm.wala.ecore.java.JavaPackage#getETypeHierarchy_Implements() + * @model containment="true" required="true" + * @generated + */ + ERelation getImplements(); + + /** + * Sets the value of the '{@link com.ibm.wala.ecore.java.ETypeHierarchy#getImplements Implements}' containment reference. + * + * + * @param value the new value of the 'Implements' containment reference. + * @see #getImplements() + * @generated + */ + void setImplements(ERelation value); + +} // ETypeHierarchy \ No newline at end of file diff --git a/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/JavaFactory.java b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/JavaFactory.java new file mode 100644 index 000000000..08c88d4a0 --- /dev/null +++ b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/JavaFactory.java @@ -0,0 +1,91 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java; + +import org.eclipse.emf.ecore.EFactory; + +/** + * + * The Factory for the model. + * It provides a create method for each non-abstract class of the model. + * + * @see com.ibm.wala.ecore.java.JavaPackage + * @generated + */ +public interface JavaFactory extends EFactory { + /** + * The singleton instance of the factory. + * + * + * @generated + */ + JavaFactory eINSTANCE = com.ibm.wala.ecore.java.impl.JavaFactoryImpl.init(); + + /** + * Returns a new object of class 'EJava Class'. + * + * + * @return a new object of class 'EJava Class'. + * @generated + */ + EJavaClass createEJavaClass(); + + /** + * Returns a new object of class 'EJava Method'. + * + * + * @return a new object of class 'EJava Method'. + * @generated + */ + EJavaMethod createEJavaMethod(); + + /** + * Returns a new object of class 'ECall Site'. + * + * + * @return a new object of class 'ECall Site'. + * @generated + */ + ECallSite createECallSite(); + + /** + * Returns a new object of class 'EClass Hierarchy'. + * + * + * @return a new object of class 'EClass Hierarchy'. + * @generated + */ + EClassHierarchy createEClassHierarchy(); + + /** + * Returns a new object of class 'EInterface Hierarchy'. + * + * + * @return a new object of class 'EInterface Hierarchy'. + * @generated + */ + EInterfaceHierarchy createEInterfaceHierarchy(); + + /** + * Returns a new object of class 'EType Hierarchy'. + * + * + * @return a new object of class 'EType Hierarchy'. + * @generated + */ + ETypeHierarchy createETypeHierarchy(); + + /** + * Returns the package supported by this factory. + * + * + * @return the package supported by this factory. + * @generated + */ + JavaPackage getJavaPackage(); + +} //JavaFactory diff --git a/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/JavaPackage.java b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/JavaPackage.java new file mode 100644 index 000000000..f12585aec --- /dev/null +++ b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/JavaPackage.java @@ -0,0 +1,755 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java; + +import com.ibm.wala.ecore.common.CommonPackage; + +import com.ibm.wala.ecore.graph.GraphPackage; + +import org.eclipse.emf.ecore.EAttribute; +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EEnum; +import org.eclipse.emf.ecore.EPackage; +import org.eclipse.emf.ecore.EReference; + +/** + * + * The Package for the model. + * It contains accessors for the meta objects to represent + *
                                + *
                              • each class,
                              • + *
                              • each feature of each class,
                              • + *
                              • each enum,
                              • + *
                              • and each data type
                              • + *
                              + * + * @see com.ibm.wala.ecore.java.JavaFactory + * @model kind="package" + * @generated + */ +public interface JavaPackage extends EPackage { + /** + * The package name. + * + * + * @generated + */ + String eNAME = "java"; + + /** + * The package namespace URI. + * + * + * @generated + */ + String eNS_URI = "http:///com/ibm/wala/wala.ecore.java"; + + /** + * The package namespace name. + * + * + * @generated + */ + String eNS_PREFIX = "com.ibm.wala.java"; + + /** + * The singleton instance of the package. + * + * + * @generated + */ + JavaPackage eINSTANCE = com.ibm.wala.ecore.java.impl.JavaPackageImpl.init(); + + /** + * The meta object id for the '{@link com.ibm.wala.ecore.java.impl.EJavaClassImpl EJava Class}' class. + * + * + * @see com.ibm.wala.ecore.java.impl.EJavaClassImpl + * @see com.ibm.wala.ecore.java.impl.JavaPackageImpl#getEJavaClass() + * @generated + */ + int EJAVA_CLASS = 0; + + /** + * The feature id for the 'Id' attribute. + * + * + * @generated + * @ordered + */ + int EJAVA_CLASS__ID = CommonPackage.EOBJECT_WITH_CONTAINER_ID__ID; + + /** + * The feature id for the 'Class Name' attribute. + * + * + * @generated + * @ordered + */ + int EJAVA_CLASS__CLASS_NAME = CommonPackage.EOBJECT_WITH_CONTAINER_ID_FEATURE_COUNT + 0; + + /** + * The feature id for the 'Loader' attribute. + * + * + * @generated + * @ordered + */ + int EJAVA_CLASS__LOADER = CommonPackage.EOBJECT_WITH_CONTAINER_ID_FEATURE_COUNT + 1; + + /** + * The number of structural features of the 'EJava Class' class. + * + * + * @generated + * @ordered + */ + int EJAVA_CLASS_FEATURE_COUNT = CommonPackage.EOBJECT_WITH_CONTAINER_ID_FEATURE_COUNT + 2; + + /** + * The meta object id for the '{@link com.ibm.wala.ecore.java.impl.EJavaMethodImpl EJava Method}' class. + * + * + * @see com.ibm.wala.ecore.java.impl.EJavaMethodImpl + * @see com.ibm.wala.ecore.java.impl.JavaPackageImpl#getEJavaMethod() + * @generated + */ + int EJAVA_METHOD = 1; + + /** + * The feature id for the 'Id' attribute. + * + * + * @generated + * @ordered + */ + int EJAVA_METHOD__ID = CommonPackage.EOBJECT_WITH_CONTAINER_ID__ID; + + /** + * The feature id for the 'Method Name' attribute. + * + * + * @generated + * @ordered + */ + int EJAVA_METHOD__METHOD_NAME = CommonPackage.EOBJECT_WITH_CONTAINER_ID_FEATURE_COUNT + 0; + + /** + * The feature id for the 'Descriptor' attribute. + * + * + * @generated + * @ordered + */ + int EJAVA_METHOD__DESCRIPTOR = CommonPackage.EOBJECT_WITH_CONTAINER_ID_FEATURE_COUNT + 1; + + /** + * The feature id for the 'Java Class' reference. + * + * + * @generated + * @ordered + */ + int EJAVA_METHOD__JAVA_CLASS = CommonPackage.EOBJECT_WITH_CONTAINER_ID_FEATURE_COUNT + 2; + + /** + * The feature id for the 'Signature' attribute. + * + * + * @generated + * @ordered + */ + int EJAVA_METHOD__SIGNATURE = CommonPackage.EOBJECT_WITH_CONTAINER_ID_FEATURE_COUNT + 3; + + /** + * The number of structural features of the 'EJava Method' class. + * + * + * @generated + * @ordered + */ + int EJAVA_METHOD_FEATURE_COUNT = CommonPackage.EOBJECT_WITH_CONTAINER_ID_FEATURE_COUNT + 4; + + /** + * The meta object id for the '{@link com.ibm.wala.ecore.java.impl.ECallSiteImpl ECall Site}' class. + * + * + * @see com.ibm.wala.ecore.java.impl.ECallSiteImpl + * @see com.ibm.wala.ecore.java.impl.JavaPackageImpl#getECallSite() + * @generated + */ + int ECALL_SITE = 2; + + /** + * The feature id for the 'Id' attribute. + * + * + * @generated + * @ordered + */ + int ECALL_SITE__ID = CommonPackage.EOBJECT_WITH_CONTAINER_ID__ID; + + /** + * The feature id for the 'Bytecode Index' attribute. + * + * + * @generated + * @ordered + */ + int ECALL_SITE__BYTECODE_INDEX = CommonPackage.EOBJECT_WITH_CONTAINER_ID_FEATURE_COUNT + 0; + + /** + * The feature id for the 'Java Method' reference. + * + * + * @generated + * @ordered + */ + int ECALL_SITE__JAVA_METHOD = CommonPackage.EOBJECT_WITH_CONTAINER_ID_FEATURE_COUNT + 1; + + /** + * The feature id for the 'Declared Target' reference. + * + * + * @generated + * @ordered + */ + int ECALL_SITE__DECLARED_TARGET = CommonPackage.EOBJECT_WITH_CONTAINER_ID_FEATURE_COUNT + 2; + + /** + * The number of structural features of the 'ECall Site' class. + * + * + * @generated + * @ordered + */ + int ECALL_SITE_FEATURE_COUNT = CommonPackage.EOBJECT_WITH_CONTAINER_ID_FEATURE_COUNT + 3; + + /** + * The meta object id for the '{@link com.ibm.wala.ecore.java.impl.EClassHierarchyImpl EClass Hierarchy}' class. + * + * + * @see com.ibm.wala.ecore.java.impl.EClassHierarchyImpl + * @see com.ibm.wala.ecore.java.impl.JavaPackageImpl#getEClassHierarchy() + * @generated + */ + int ECLASS_HIERARCHY = 3; + + /** + * The feature id for the 'Nodes' reference. + * + * + * @generated + * @ordered + */ + int ECLASS_HIERARCHY__NODES = GraphPackage.ETREE__NODES; + + /** + * The feature id for the 'Edges' containment reference. + * + * + * @generated + * @ordered + */ + int ECLASS_HIERARCHY__EDGES = GraphPackage.ETREE__EDGES; + + /** + * The number of structural features of the 'EClass Hierarchy' class. + * + * + * @generated + * @ordered + */ + int ECLASS_HIERARCHY_FEATURE_COUNT = GraphPackage.ETREE_FEATURE_COUNT + 0; + + /** + * The meta object id for the '{@link com.ibm.wala.ecore.java.impl.EInterfaceHierarchyImpl EInterface Hierarchy}' class. + * + * + * @see com.ibm.wala.ecore.java.impl.EInterfaceHierarchyImpl + * @see com.ibm.wala.ecore.java.impl.JavaPackageImpl#getEInterfaceHierarchy() + * @generated + */ + int EINTERFACE_HIERARCHY = 4; + + /** + * The feature id for the 'Nodes' reference. + * + * + * @generated + * @ordered + */ + int EINTERFACE_HIERARCHY__NODES = GraphPackage.EGRAPH__NODES; + + /** + * The feature id for the 'Edges' containment reference. + * + * + * @generated + * @ordered + */ + int EINTERFACE_HIERARCHY__EDGES = GraphPackage.EGRAPH__EDGES; + + /** + * The number of structural features of the 'EInterface Hierarchy' class. + * + * + * @generated + * @ordered + */ + int EINTERFACE_HIERARCHY_FEATURE_COUNT = GraphPackage.EGRAPH_FEATURE_COUNT + 0; + + /** + * The meta object id for the '{@link com.ibm.wala.ecore.java.impl.ETypeHierarchyImpl EType Hierarchy}' class. + * + * + * @see com.ibm.wala.ecore.java.impl.ETypeHierarchyImpl + * @see com.ibm.wala.ecore.java.impl.JavaPackageImpl#getETypeHierarchy() + * @generated + */ + int ETYPE_HIERARCHY = 5; + + /** + * The feature id for the 'Classes' containment reference. + * + * + * @generated + * @ordered + */ + int ETYPE_HIERARCHY__CLASSES = 0; + + /** + * The feature id for the 'Interfaces' containment reference. + * + * + * @generated + * @ordered + */ + int ETYPE_HIERARCHY__INTERFACES = 1; + + /** + * The feature id for the 'Implements' containment reference. + * + * + * @generated + * @ordered + */ + int ETYPE_HIERARCHY__IMPLEMENTS = 2; + + /** + * The number of structural features of the 'EType Hierarchy' class. + * + * + * @generated + * @ordered + */ + int ETYPE_HIERARCHY_FEATURE_COUNT = 3; + + /** + * The meta object id for the '{@link com.ibm.wala.ecore.java.EClassLoaderName EClass Loader Name}' enum. + * + * + * @see com.ibm.wala.ecore.java.EClassLoaderName + * @see com.ibm.wala.ecore.java.impl.JavaPackageImpl#getEClassLoaderName() + * @generated + */ + int ECLASS_LOADER_NAME = 6; + + + /** + * Returns the meta object for class '{@link com.ibm.wala.ecore.java.EJavaClass EJava Class}'. + * + * + * @return the meta object for class 'EJava Class'. + * @see com.ibm.wala.ecore.java.EJavaClass + * @generated + */ + EClass getEJavaClass(); + + /** + * Returns the meta object for the attribute '{@link com.ibm.wala.ecore.java.EJavaClass#getClassName Class Name}'. + * + * + * @return the meta object for the attribute 'Class Name'. + * @see com.ibm.wala.ecore.java.EJavaClass#getClassName() + * @see #getEJavaClass() + * @generated + */ + EAttribute getEJavaClass_ClassName(); + + /** + * Returns the meta object for the attribute '{@link com.ibm.wala.ecore.java.EJavaClass#getLoader Loader}'. + * + * + * @return the meta object for the attribute 'Loader'. + * @see com.ibm.wala.ecore.java.EJavaClass#getLoader() + * @see #getEJavaClass() + * @generated + */ + EAttribute getEJavaClass_Loader(); + + /** + * Returns the meta object for class '{@link com.ibm.wala.ecore.java.EJavaMethod EJava Method}'. + * + * + * @return the meta object for class 'EJava Method'. + * @see com.ibm.wala.ecore.java.EJavaMethod + * @generated + */ + EClass getEJavaMethod(); + + /** + * Returns the meta object for the attribute '{@link com.ibm.wala.ecore.java.EJavaMethod#getMethodName Method Name}'. + * + * + * @return the meta object for the attribute 'Method Name'. + * @see com.ibm.wala.ecore.java.EJavaMethod#getMethodName() + * @see #getEJavaMethod() + * @generated + */ + EAttribute getEJavaMethod_MethodName(); + + /** + * Returns the meta object for the attribute '{@link com.ibm.wala.ecore.java.EJavaMethod#getDescriptor Descriptor}'. + * + * + * @return the meta object for the attribute 'Descriptor'. + * @see com.ibm.wala.ecore.java.EJavaMethod#getDescriptor() + * @see #getEJavaMethod() + * @generated + */ + EAttribute getEJavaMethod_Descriptor(); + + /** + * Returns the meta object for the reference '{@link com.ibm.wala.ecore.java.EJavaMethod#getJavaClass Java Class}'. + * + * + * @return the meta object for the reference 'Java Class'. + * @see com.ibm.wala.ecore.java.EJavaMethod#getJavaClass() + * @see #getEJavaMethod() + * @generated + */ + EReference getEJavaMethod_JavaClass(); + + /** + * Returns the meta object for the attribute '{@link com.ibm.wala.ecore.java.EJavaMethod#getSignature Signature}'. + * + * + * @return the meta object for the attribute 'Signature'. + * @see com.ibm.wala.ecore.java.EJavaMethod#getSignature() + * @see #getEJavaMethod() + * @generated + */ + EAttribute getEJavaMethod_Signature(); + + /** + * Returns the meta object for class '{@link com.ibm.wala.ecore.java.ECallSite ECall Site}'. + * + * + * @return the meta object for class 'ECall Site'. + * @see com.ibm.wala.ecore.java.ECallSite + * @generated + */ + EClass getECallSite(); + + /** + * Returns the meta object for the attribute '{@link com.ibm.wala.ecore.java.ECallSite#getBytecodeIndex Bytecode Index}'. + * + * + * @return the meta object for the attribute 'Bytecode Index'. + * @see com.ibm.wala.ecore.java.ECallSite#getBytecodeIndex() + * @see #getECallSite() + * @generated + */ + EAttribute getECallSite_BytecodeIndex(); + + /** + * Returns the meta object for the reference '{@link com.ibm.wala.ecore.java.ECallSite#getJavaMethod Java Method}'. + * + * + * @return the meta object for the reference 'Java Method'. + * @see com.ibm.wala.ecore.java.ECallSite#getJavaMethod() + * @see #getECallSite() + * @generated + */ + EReference getECallSite_JavaMethod(); + + /** + * Returns the meta object for the reference '{@link com.ibm.wala.ecore.java.ECallSite#getDeclaredTarget Declared Target}'. + * + * + * @return the meta object for the reference 'Declared Target'. + * @see com.ibm.wala.ecore.java.ECallSite#getDeclaredTarget() + * @see #getECallSite() + * @generated + */ + EReference getECallSite_DeclaredTarget(); + + /** + * Returns the meta object for class '{@link com.ibm.wala.ecore.java.EClassHierarchy EClass Hierarchy}'. + * + * + * @return the meta object for class 'EClass Hierarchy'. + * @see com.ibm.wala.ecore.java.EClassHierarchy + * @generated + */ + EClass getEClassHierarchy(); + + /** + * Returns the meta object for class '{@link com.ibm.wala.ecore.java.EInterfaceHierarchy EInterface Hierarchy}'. + * + * + * @return the meta object for class 'EInterface Hierarchy'. + * @see com.ibm.wala.ecore.java.EInterfaceHierarchy + * @generated + */ + EClass getEInterfaceHierarchy(); + + /** + * Returns the meta object for class '{@link com.ibm.wala.ecore.java.ETypeHierarchy EType Hierarchy}'. + * + * + * @return the meta object for class 'EType Hierarchy'. + * @see com.ibm.wala.ecore.java.ETypeHierarchy + * @generated + */ + EClass getETypeHierarchy(); + + /** + * Returns the meta object for the containment reference '{@link com.ibm.wala.ecore.java.ETypeHierarchy#getClasses Classes}'. + * + * + * @return the meta object for the containment reference 'Classes'. + * @see com.ibm.wala.ecore.java.ETypeHierarchy#getClasses() + * @see #getETypeHierarchy() + * @generated + */ + EReference getETypeHierarchy_Classes(); + + /** + * Returns the meta object for the containment reference '{@link com.ibm.wala.ecore.java.ETypeHierarchy#getInterfaces Interfaces}'. + * + * + * @return the meta object for the containment reference 'Interfaces'. + * @see com.ibm.wala.ecore.java.ETypeHierarchy#getInterfaces() + * @see #getETypeHierarchy() + * @generated + */ + EReference getETypeHierarchy_Interfaces(); + + /** + * Returns the meta object for the containment reference '{@link com.ibm.wala.ecore.java.ETypeHierarchy#getImplements Implements}'. + * + * + * @return the meta object for the containment reference 'Implements'. + * @see com.ibm.wala.ecore.java.ETypeHierarchy#getImplements() + * @see #getETypeHierarchy() + * @generated + */ + EReference getETypeHierarchy_Implements(); + + /** + * Returns the meta object for enum '{@link com.ibm.wala.ecore.java.EClassLoaderName EClass Loader Name}'. + * + * + * @return the meta object for enum 'EClass Loader Name'. + * @see com.ibm.wala.ecore.java.EClassLoaderName + * @generated + */ + EEnum getEClassLoaderName(); + + /** + * Returns the factory that creates the instances of the model. + * + * + * @return the factory that creates the instances of the model. + * @generated + */ + JavaFactory getJavaFactory(); + + /** + * + * Defines literals for the meta objects that represent + *
                                + *
                              • each class,
                              • + *
                              • each feature of each class,
                              • + *
                              • each enum,
                              • + *
                              • and each data type
                              • + *
                              + * + * @generated + */ + interface Literals { + /** + * The meta object literal for the '{@link com.ibm.wala.ecore.java.impl.EJavaClassImpl EJava Class}' class. + * + * + * @see com.ibm.wala.ecore.java.impl.EJavaClassImpl + * @see com.ibm.wala.ecore.java.impl.JavaPackageImpl#getEJavaClass() + * @generated + */ + EClass EJAVA_CLASS = eINSTANCE.getEJavaClass(); + + /** + * The meta object literal for the 'Class Name' attribute feature. + * + * + * @generated + */ + EAttribute EJAVA_CLASS__CLASS_NAME = eINSTANCE.getEJavaClass_ClassName(); + + /** + * The meta object literal for the 'Loader' attribute feature. + * + * + * @generated + */ + EAttribute EJAVA_CLASS__LOADER = eINSTANCE.getEJavaClass_Loader(); + + /** + * The meta object literal for the '{@link com.ibm.wala.ecore.java.impl.EJavaMethodImpl EJava Method}' class. + * + * + * @see com.ibm.wala.ecore.java.impl.EJavaMethodImpl + * @see com.ibm.wala.ecore.java.impl.JavaPackageImpl#getEJavaMethod() + * @generated + */ + EClass EJAVA_METHOD = eINSTANCE.getEJavaMethod(); + + /** + * The meta object literal for the 'Method Name' attribute feature. + * + * + * @generated + */ + EAttribute EJAVA_METHOD__METHOD_NAME = eINSTANCE.getEJavaMethod_MethodName(); + + /** + * The meta object literal for the 'Descriptor' attribute feature. + * + * + * @generated + */ + EAttribute EJAVA_METHOD__DESCRIPTOR = eINSTANCE.getEJavaMethod_Descriptor(); + + /** + * The meta object literal for the 'Java Class' reference feature. + * + * + * @generated + */ + EReference EJAVA_METHOD__JAVA_CLASS = eINSTANCE.getEJavaMethod_JavaClass(); + + /** + * The meta object literal for the 'Signature' attribute feature. + * + * + * @generated + */ + EAttribute EJAVA_METHOD__SIGNATURE = eINSTANCE.getEJavaMethod_Signature(); + + /** + * The meta object literal for the '{@link com.ibm.wala.ecore.java.impl.ECallSiteImpl ECall Site}' class. + * + * + * @see com.ibm.wala.ecore.java.impl.ECallSiteImpl + * @see com.ibm.wala.ecore.java.impl.JavaPackageImpl#getECallSite() + * @generated + */ + EClass ECALL_SITE = eINSTANCE.getECallSite(); + + /** + * The meta object literal for the 'Bytecode Index' attribute feature. + * + * + * @generated + */ + EAttribute ECALL_SITE__BYTECODE_INDEX = eINSTANCE.getECallSite_BytecodeIndex(); + + /** + * The meta object literal for the 'Java Method' reference feature. + * + * + * @generated + */ + EReference ECALL_SITE__JAVA_METHOD = eINSTANCE.getECallSite_JavaMethod(); + + /** + * The meta object literal for the 'Declared Target' reference feature. + * + * + * @generated + */ + EReference ECALL_SITE__DECLARED_TARGET = eINSTANCE.getECallSite_DeclaredTarget(); + + /** + * The meta object literal for the '{@link com.ibm.wala.ecore.java.impl.EClassHierarchyImpl EClass Hierarchy}' class. + * + * + * @see com.ibm.wala.ecore.java.impl.EClassHierarchyImpl + * @see com.ibm.wala.ecore.java.impl.JavaPackageImpl#getEClassHierarchy() + * @generated + */ + EClass ECLASS_HIERARCHY = eINSTANCE.getEClassHierarchy(); + + /** + * The meta object literal for the '{@link com.ibm.wala.ecore.java.impl.EInterfaceHierarchyImpl EInterface Hierarchy}' class. + * + * + * @see com.ibm.wala.ecore.java.impl.EInterfaceHierarchyImpl + * @see com.ibm.wala.ecore.java.impl.JavaPackageImpl#getEInterfaceHierarchy() + * @generated + */ + EClass EINTERFACE_HIERARCHY = eINSTANCE.getEInterfaceHierarchy(); + + /** + * The meta object literal for the '{@link com.ibm.wala.ecore.java.impl.ETypeHierarchyImpl EType Hierarchy}' class. + * + * + * @see com.ibm.wala.ecore.java.impl.ETypeHierarchyImpl + * @see com.ibm.wala.ecore.java.impl.JavaPackageImpl#getETypeHierarchy() + * @generated + */ + EClass ETYPE_HIERARCHY = eINSTANCE.getETypeHierarchy(); + + /** + * The meta object literal for the 'Classes' containment reference feature. + * + * + * @generated + */ + EReference ETYPE_HIERARCHY__CLASSES = eINSTANCE.getETypeHierarchy_Classes(); + + /** + * The meta object literal for the 'Interfaces' containment reference feature. + * + * + * @generated + */ + EReference ETYPE_HIERARCHY__INTERFACES = eINSTANCE.getETypeHierarchy_Interfaces(); + + /** + * The meta object literal for the 'Implements' containment reference feature. + * + * + * @generated + */ + EReference ETYPE_HIERARCHY__IMPLEMENTS = eINSTANCE.getETypeHierarchy_Implements(); + + /** + * The meta object literal for the '{@link com.ibm.wala.ecore.java.EClassLoaderName EClass Loader Name}' enum. + * + * + * @see com.ibm.wala.ecore.java.EClassLoaderName + * @see com.ibm.wala.ecore.java.impl.JavaPackageImpl#getEClassLoaderName() + * @generated + */ + EEnum ECLASS_LOADER_NAME = eINSTANCE.getEClassLoaderName(); + + } + +} //JavaPackage diff --git a/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/callGraph/CallGraphFactory.java b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/callGraph/CallGraphFactory.java new file mode 100644 index 000000000..ecdb525b0 --- /dev/null +++ b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/callGraph/CallGraphFactory.java @@ -0,0 +1,46 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java.callGraph; + +import org.eclipse.emf.ecore.EFactory; + +/** + * + * The Factory for the model. + * It provides a create method for each non-abstract class of the model. + * + * @see com.ibm.wala.ecore.java.callGraph.CallGraphPackage + * @generated + */ +public interface CallGraphFactory extends EFactory { + /** + * The singleton instance of the factory. + * + * + * @generated + */ + CallGraphFactory eINSTANCE = com.ibm.wala.ecore.java.callGraph.impl.CallGraphFactoryImpl.init(); + + /** + * Returns a new object of class 'ECall Graph'. + * + * + * @return a new object of class 'ECall Graph'. + * @generated + */ + ECallGraph createECallGraph(); + + /** + * Returns the package supported by this factory. + * + * + * @return the package supported by this factory. + * @generated + */ + CallGraphPackage getCallGraphPackage(); + +} //CallGraphFactory diff --git a/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/callGraph/CallGraphPackage.java b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/callGraph/CallGraphPackage.java new file mode 100644 index 000000000..0160c19a5 --- /dev/null +++ b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/callGraph/CallGraphPackage.java @@ -0,0 +1,173 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java.callGraph; + +import com.ibm.wala.ecore.graph.GraphPackage; + +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EPackage; +import org.eclipse.emf.ecore.EReference; + +/** + * + * The Package for the model. + * It contains accessors for the meta objects to represent + *
                                + *
                              • each class,
                              • + *
                              • each feature of each class,
                              • + *
                              • each enum,
                              • + *
                              • and each data type
                              • + *
                              + * + * @see com.ibm.wala.ecore.java.callGraph.CallGraphFactory + * @model kind="package" + * @generated + */ +public interface CallGraphPackage extends EPackage { + /** + * The package name. + * + * + * @generated + */ + String eNAME = "callGraph"; + + /** + * The package namespace URI. + * + * + * @generated + */ + String eNS_URI = "http:///com/ibm/wala/wala.ecore.java.callGraph"; + + /** + * The package namespace name. + * + * + * @generated + */ + String eNS_PREFIX = "com.ibm.wala.java.callGraph"; + + /** + * The singleton instance of the package. + * + * + * @generated + */ + CallGraphPackage eINSTANCE = com.ibm.wala.ecore.java.callGraph.impl.CallGraphPackageImpl.init(); + + /** + * The meta object id for the '{@link com.ibm.wala.ecore.java.callGraph.impl.ECallGraphImpl ECall Graph}' class. + * + * + * @see com.ibm.wala.ecore.java.callGraph.impl.ECallGraphImpl + * @see com.ibm.wala.ecore.java.callGraph.impl.CallGraphPackageImpl#getECallGraph() + * @generated + */ + int ECALL_GRAPH = 0; + + /** + * The feature id for the 'Nodes' reference. + * + * + * @generated + * @ordered + */ + int ECALL_GRAPH__NODES = GraphPackage.EGRAPH__NODES; + + /** + * The feature id for the 'Edges' containment reference. + * + * + * @generated + * @ordered + */ + int ECALL_GRAPH__EDGES = GraphPackage.EGRAPH__EDGES; + + /** + * The feature id for the 'Entrypoints' reference list. + * + * + * @generated + * @ordered + */ + int ECALL_GRAPH__ENTRYPOINTS = GraphPackage.EGRAPH_FEATURE_COUNT + 0; + + /** + * The number of structural features of the 'ECall Graph' class. + * + * + * @generated + * @ordered + */ + int ECALL_GRAPH_FEATURE_COUNT = GraphPackage.EGRAPH_FEATURE_COUNT + 1; + + + /** + * Returns the meta object for class '{@link com.ibm.wala.ecore.java.callGraph.ECallGraph ECall Graph}'. + * + * + * @return the meta object for class 'ECall Graph'. + * @see com.ibm.wala.ecore.java.callGraph.ECallGraph + * @generated + */ + EClass getECallGraph(); + + /** + * Returns the meta object for the reference list '{@link com.ibm.wala.ecore.java.callGraph.ECallGraph#getEntrypoints Entrypoints}'. + * + * + * @return the meta object for the reference list 'Entrypoints'. + * @see com.ibm.wala.ecore.java.callGraph.ECallGraph#getEntrypoints() + * @see #getECallGraph() + * @generated + */ + EReference getECallGraph_Entrypoints(); + + /** + * Returns the factory that creates the instances of the model. + * + * + * @return the factory that creates the instances of the model. + * @generated + */ + CallGraphFactory getCallGraphFactory(); + + /** + * + * Defines literals for the meta objects that represent + *
                                + *
                              • each class,
                              • + *
                              • each feature of each class,
                              • + *
                              • each enum,
                              • + *
                              • and each data type
                              • + *
                              + * + * @generated + */ + interface Literals { + /** + * The meta object literal for the '{@link com.ibm.wala.ecore.java.callGraph.impl.ECallGraphImpl ECall Graph}' class. + * + * + * @see com.ibm.wala.ecore.java.callGraph.impl.ECallGraphImpl + * @see com.ibm.wala.ecore.java.callGraph.impl.CallGraphPackageImpl#getECallGraph() + * @generated + */ + EClass ECALL_GRAPH = eINSTANCE.getECallGraph(); + + /** + * The meta object literal for the 'Entrypoints' reference list feature. + * + * + * @generated + */ + EReference ECALL_GRAPH__ENTRYPOINTS = eINSTANCE.getECallGraph_Entrypoints(); + + } + +} //CallGraphPackage diff --git a/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/callGraph/ECallGraph.java b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/callGraph/ECallGraph.java new file mode 100644 index 000000000..3571cb7c4 --- /dev/null +++ b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/callGraph/ECallGraph.java @@ -0,0 +1,46 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java.callGraph; + +import com.ibm.wala.ecore.graph.EGraph; + +import org.eclipse.emf.common.util.EList; + +/** + * + * A representation of the model object 'ECall Graph'. + * + * + *

                              + * The following features are supported: + *

                                + *
                              • {@link com.ibm.wala.ecore.java.callGraph.ECallGraph#getEntrypoints Entrypoints}
                              • + *
                              + *

                              + * + * @see com.ibm.wala.ecore.java.callGraph.CallGraphPackage#getECallGraph() + * @model + * @generated + */ +public interface ECallGraph extends EGraph { + /** + * Returns the value of the 'Entrypoints' reference list. + * The list contents are of type {@link com.ibm.wala.ecore.java.EJavaMethod}. + * + *

                              + * If the meaning of the 'Entrypoints' reference list isn't clear, + * there really should be more of a description here... + *

                              + * + * @return the value of the 'Entrypoints' reference list. + * @see com.ibm.wala.ecore.java.callGraph.CallGraphPackage#getECallGraph_Entrypoints() + * @model type="com.ibm.wala.ecore.java.EJavaMethod" + * @generated + */ + EList getEntrypoints(); + +} // ECallGraph \ No newline at end of file diff --git a/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/callGraph/impl/CallGraphFactoryImpl.java b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/callGraph/impl/CallGraphFactoryImpl.java new file mode 100644 index 000000000..cb20e2087 --- /dev/null +++ b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/callGraph/impl/CallGraphFactoryImpl.java @@ -0,0 +1,97 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java.callGraph.impl; + +import com.ibm.wala.ecore.java.callGraph.*; + +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EPackage; + +import org.eclipse.emf.ecore.impl.EFactoryImpl; + +import org.eclipse.emf.ecore.plugin.EcorePlugin; + +/** + * + * An implementation of the model Factory. + * + * @generated + */ +public class CallGraphFactoryImpl extends EFactoryImpl implements CallGraphFactory { + /** + * Creates the default factory implementation. + * + * + * @generated + */ + public static CallGraphFactory init() { + try { + CallGraphFactory theCallGraphFactory = (CallGraphFactory)EPackage.Registry.INSTANCE.getEFactory("http:///com/ibm/wala/wala.ecore.java.callGraph"); + if (theCallGraphFactory != null) { + return theCallGraphFactory; + } + } + catch (Exception exception) { + EcorePlugin.INSTANCE.log(exception); + } + return new CallGraphFactoryImpl(); + } + + /** + * Creates an instance of the factory. + * + * + * @generated + */ + public CallGraphFactoryImpl() { + super(); + } + + /** + * + * + * @generated + */ + public EObject create(EClass eClass) { + switch (eClass.getClassifierID()) { + case CallGraphPackage.ECALL_GRAPH: return createECallGraph(); + default: + throw new IllegalArgumentException("The class '" + eClass.getName() + "' is not a valid classifier"); + } + } + + /** + * + * + * @generated + */ + public ECallGraph createECallGraph() { + ECallGraphImpl eCallGraph = new ECallGraphImpl(); + return eCallGraph; + } + + /** + * + * + * @generated + */ + public CallGraphPackage getCallGraphPackage() { + return (CallGraphPackage)getEPackage(); + } + + /** + * + * + * @deprecated + * @generated + */ + public static CallGraphPackage getPackage() { + return CallGraphPackage.eINSTANCE; + } + +} //CallGraphFactoryImpl diff --git a/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/callGraph/impl/CallGraphPackageImpl.java b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/callGraph/impl/CallGraphPackageImpl.java new file mode 100644 index 000000000..ce63f9c20 --- /dev/null +++ b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/callGraph/impl/CallGraphPackageImpl.java @@ -0,0 +1,244 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java.callGraph.impl; + +import com.ibm.wala.ecore.common.CommonPackage; + +import com.ibm.wala.ecore.common.impl.CommonPackageImpl; + +import com.ibm.wala.ecore.graph.GraphPackage; + +import com.ibm.wala.ecore.graph.impl.GraphPackageImpl; + +import com.ibm.wala.ecore.j2ee.scope.J2EEScopePackage; + +import com.ibm.wala.ecore.j2ee.scope.impl.J2EEScopePackageImpl; + +import com.ibm.wala.ecore.java.JavaPackage; + +import com.ibm.wala.ecore.java.callGraph.CallGraphFactory; +import com.ibm.wala.ecore.java.callGraph.CallGraphPackage; +import com.ibm.wala.ecore.java.callGraph.ECallGraph; + +import com.ibm.wala.ecore.java.impl.JavaPackageImpl; + +import com.ibm.wala.ecore.java.pointerAnalysis.PointerAnalysisPackage; + +import com.ibm.wala.ecore.java.pointerAnalysis.impl.PointerAnalysisPackageImpl; + +import com.ibm.wala.ecore.java.scope.JavaScopePackage; + +import com.ibm.wala.ecore.java.scope.impl.JavaScopePackageImpl; + +import com.ibm.wala.ecore.perf.PerfPackage; + +import com.ibm.wala.ecore.perf.impl.PerfPackageImpl; + +import com.ibm.wala.ecore.regex.RegexPackage; + +import com.ibm.wala.ecore.regex.impl.RegexPackageImpl; + +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EPackage; +import org.eclipse.emf.ecore.EReference; + +import org.eclipse.emf.ecore.impl.EPackageImpl; + +/** + * + * An implementation of the model Package. + * + * @generated + */ +public class CallGraphPackageImpl extends EPackageImpl implements CallGraphPackage { + /** + * + * + * @generated + */ + private EClass eCallGraphEClass = null; + + /** + * Creates an instance of the model Package, registered with + * {@link org.eclipse.emf.ecore.EPackage.Registry EPackage.Registry} by the package + * package URI value. + *

                              Note: the correct way to create the package is via the static + * factory method {@link #init init()}, which also performs + * initialization of the package, or returns the registered package, + * if one already exists. + * + * + * @see org.eclipse.emf.ecore.EPackage.Registry + * @see com.ibm.wala.ecore.java.callGraph.CallGraphPackage#eNS_URI + * @see #init() + * @generated + */ + private CallGraphPackageImpl() { + super(eNS_URI, CallGraphFactory.eINSTANCE); + } + + /** + * + * + * @generated + */ + private static boolean isInited = false; + + /** + * Creates, registers, and initializes the Package for this + * model, and for any others upon which it depends. Simple + * dependencies are satisfied by calling this method on all + * dependent packages before doing anything else. This method drives + * initialization for interdependent packages directly, in parallel + * with this package, itself. + *

                              Of this package and its interdependencies, all packages which + * have not yet been registered by their URI values are first created + * and registered. The packages are then initialized in two steps: + * meta-model objects for all of the packages are created before any + * are initialized, since one package's meta-model objects may refer to + * those of another. + *

                              Invocation of this method will not affect any packages that have + * already been initialized. + * + * + * @see #eNS_URI + * @see #createPackageContents() + * @see #initializePackageContents() + * @generated + */ + public static CallGraphPackage init() { + if (isInited) return (CallGraphPackage)EPackage.Registry.INSTANCE.getEPackage(CallGraphPackage.eNS_URI); + + // Obtain or create and register package + CallGraphPackageImpl theCallGraphPackage = (CallGraphPackageImpl)(EPackage.Registry.INSTANCE.getEPackage(eNS_URI) instanceof CallGraphPackageImpl ? EPackage.Registry.INSTANCE.getEPackage(eNS_URI) : new CallGraphPackageImpl()); + + isInited = true; + + // Obtain or create and register interdependencies + GraphPackageImpl theGraphPackage = (GraphPackageImpl)(EPackage.Registry.INSTANCE.getEPackage(GraphPackage.eNS_URI) instanceof GraphPackageImpl ? EPackage.Registry.INSTANCE.getEPackage(GraphPackage.eNS_URI) : GraphPackage.eINSTANCE); + CommonPackageImpl theCommonPackage = (CommonPackageImpl)(EPackage.Registry.INSTANCE.getEPackage(CommonPackage.eNS_URI) instanceof CommonPackageImpl ? EPackage.Registry.INSTANCE.getEPackage(CommonPackage.eNS_URI) : CommonPackage.eINSTANCE); + RegexPackageImpl theRegexPackage = (RegexPackageImpl)(EPackage.Registry.INSTANCE.getEPackage(RegexPackage.eNS_URI) instanceof RegexPackageImpl ? EPackage.Registry.INSTANCE.getEPackage(RegexPackage.eNS_URI) : RegexPackage.eINSTANCE); + PerfPackageImpl thePerfPackage = (PerfPackageImpl)(EPackage.Registry.INSTANCE.getEPackage(PerfPackage.eNS_URI) instanceof PerfPackageImpl ? EPackage.Registry.INSTANCE.getEPackage(PerfPackage.eNS_URI) : PerfPackage.eINSTANCE); + JavaPackageImpl theJavaPackage = (JavaPackageImpl)(EPackage.Registry.INSTANCE.getEPackage(JavaPackage.eNS_URI) instanceof JavaPackageImpl ? EPackage.Registry.INSTANCE.getEPackage(JavaPackage.eNS_URI) : JavaPackage.eINSTANCE); + PointerAnalysisPackageImpl thePointerAnalysisPackage = (PointerAnalysisPackageImpl)(EPackage.Registry.INSTANCE.getEPackage(PointerAnalysisPackage.eNS_URI) instanceof PointerAnalysisPackageImpl ? EPackage.Registry.INSTANCE.getEPackage(PointerAnalysisPackage.eNS_URI) : PointerAnalysisPackage.eINSTANCE); + JavaScopePackageImpl theJavaScopePackage = (JavaScopePackageImpl)(EPackage.Registry.INSTANCE.getEPackage(JavaScopePackage.eNS_URI) instanceof JavaScopePackageImpl ? EPackage.Registry.INSTANCE.getEPackage(JavaScopePackage.eNS_URI) : JavaScopePackage.eINSTANCE); + J2EEScopePackageImpl theJ2EEScopePackage = (J2EEScopePackageImpl)(EPackage.Registry.INSTANCE.getEPackage(J2EEScopePackage.eNS_URI) instanceof J2EEScopePackageImpl ? EPackage.Registry.INSTANCE.getEPackage(J2EEScopePackage.eNS_URI) : J2EEScopePackage.eINSTANCE); + + // Create package meta-data objects + theCallGraphPackage.createPackageContents(); + theGraphPackage.createPackageContents(); + theCommonPackage.createPackageContents(); + theRegexPackage.createPackageContents(); + thePerfPackage.createPackageContents(); + theJavaPackage.createPackageContents(); + thePointerAnalysisPackage.createPackageContents(); + theJavaScopePackage.createPackageContents(); + theJ2EEScopePackage.createPackageContents(); + + // Initialize created meta-data + theCallGraphPackage.initializePackageContents(); + theGraphPackage.initializePackageContents(); + theCommonPackage.initializePackageContents(); + theRegexPackage.initializePackageContents(); + thePerfPackage.initializePackageContents(); + theJavaPackage.initializePackageContents(); + thePointerAnalysisPackage.initializePackageContents(); + theJavaScopePackage.initializePackageContents(); + theJ2EEScopePackage.initializePackageContents(); + + // Mark meta-data to indicate it can't be changed + theCallGraphPackage.freeze(); + + return theCallGraphPackage; + } + + /** + * + * + * @generated + */ + public EClass getECallGraph() { + return eCallGraphEClass; + } + + /** + * + * + * @generated + */ + public EReference getECallGraph_Entrypoints() { + return (EReference)eCallGraphEClass.getEStructuralFeatures().get(0); + } + + /** + * + * + * @generated + */ + public CallGraphFactory getCallGraphFactory() { + return (CallGraphFactory)getEFactoryInstance(); + } + + /** + * + * + * @generated + */ + private boolean isCreated = false; + + /** + * Creates the meta-model objects for the package. This method is + * guarded to have no affect on any invocation but its first. + * + * + * @generated + */ + public void createPackageContents() { + if (isCreated) return; + isCreated = true; + + // Create classes and their features + eCallGraphEClass = createEClass(ECALL_GRAPH); + createEReference(eCallGraphEClass, ECALL_GRAPH__ENTRYPOINTS); + } + + /** + * + * + * @generated + */ + private boolean isInitialized = false; + + /** + * Complete the initialization of the package and its meta-model. This + * method is guarded to have no affect on any invocation but its first. + * + * + * @generated + */ + public void initializePackageContents() { + if (isInitialized) return; + isInitialized = true; + + // Initialize package + setName(eNAME); + setNsPrefix(eNS_PREFIX); + setNsURI(eNS_URI); + + // Obtain other dependent packages + GraphPackage theGraphPackage = (GraphPackage)EPackage.Registry.INSTANCE.getEPackage(GraphPackage.eNS_URI); + JavaPackage theJavaPackage = (JavaPackage)EPackage.Registry.INSTANCE.getEPackage(JavaPackage.eNS_URI); + + // Add supertypes to classes + eCallGraphEClass.getESuperTypes().add(theGraphPackage.getEGraph()); + + // Initialize classes and features; add operations and parameters + initEClass(eCallGraphEClass, ECallGraph.class, "ECallGraph", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); + initEReference(getECallGraph_Entrypoints(), theJavaPackage.getEJavaMethod(), null, "entrypoints", null, 0, -1, ECallGraph.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_COMPOSITE, IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); + } + +} //CallGraphPackageImpl diff --git a/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/callGraph/impl/ECallGraphImpl.java b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/callGraph/impl/ECallGraphImpl.java new file mode 100644 index 000000000..511f432a0 --- /dev/null +++ b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/callGraph/impl/ECallGraphImpl.java @@ -0,0 +1,133 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java.callGraph.impl; + +import com.ibm.wala.ecore.graph.impl.EGraphImpl; + +import com.ibm.wala.ecore.java.EJavaMethod; + +import com.ibm.wala.ecore.java.callGraph.CallGraphPackage; +import com.ibm.wala.ecore.java.callGraph.ECallGraph; + +import java.util.Collection; + +import org.eclipse.emf.common.util.EList; + +import org.eclipse.emf.ecore.EClass; + +import org.eclipse.emf.ecore.util.EObjectResolvingEList; + +/** + * + * An implementation of the model object 'ECall Graph'. + * + *

                              + * The following features are implemented: + *

                                + *
                              • {@link com.ibm.wala.ecore.java.callGraph.impl.ECallGraphImpl#getEntrypoints Entrypoints}
                              • + *
                              + *

                              + * + * @generated + */ +public class ECallGraphImpl extends EGraphImpl implements ECallGraph { + /** + * The cached value of the '{@link #getEntrypoints() Entrypoints}' reference list. + * + * + * @see #getEntrypoints() + * @generated + * @ordered + */ + protected EList entrypoints = null; + + /** + * + * + * @generated + */ + protected ECallGraphImpl() { + super(); + } + + /** + * + * + * @generated + */ + protected EClass eStaticClass() { + return CallGraphPackage.Literals.ECALL_GRAPH; + } + + /** + * + * + * @generated + */ + public EList getEntrypoints() { + if (entrypoints == null) { + entrypoints = new EObjectResolvingEList(EJavaMethod.class, this, CallGraphPackage.ECALL_GRAPH__ENTRYPOINTS); + } + return entrypoints; + } + + /** + * + * + * @generated + */ + public Object eGet(int featureID, boolean resolve, boolean coreType) { + switch (featureID) { + case CallGraphPackage.ECALL_GRAPH__ENTRYPOINTS: + return getEntrypoints(); + } + return super.eGet(featureID, resolve, coreType); + } + + /** + * + * + * @generated + */ + public void eSet(int featureID, Object newValue) { + switch (featureID) { + case CallGraphPackage.ECALL_GRAPH__ENTRYPOINTS: + getEntrypoints().clear(); + getEntrypoints().addAll((Collection)newValue); + return; + } + super.eSet(featureID, newValue); + } + + /** + * + * + * @generated + */ + public void eUnset(int featureID) { + switch (featureID) { + case CallGraphPackage.ECALL_GRAPH__ENTRYPOINTS: + getEntrypoints().clear(); + return; + } + super.eUnset(featureID); + } + + /** + * + * + * @generated + */ + public boolean eIsSet(int featureID) { + switch (featureID) { + case CallGraphPackage.ECALL_GRAPH__ENTRYPOINTS: + return entrypoints != null && !entrypoints.isEmpty(); + } + return super.eIsSet(featureID); + } + +} //ECallGraphImpl \ No newline at end of file diff --git a/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/callGraph/util/CallGraphAdapterFactory.java b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/callGraph/util/CallGraphAdapterFactory.java new file mode 100644 index 000000000..b1b3d1669 --- /dev/null +++ b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/callGraph/util/CallGraphAdapterFactory.java @@ -0,0 +1,139 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java.callGraph.util; + +import com.ibm.wala.ecore.graph.EGraph; + +import com.ibm.wala.ecore.java.callGraph.*; + +import org.eclipse.emf.common.notify.Adapter; +import org.eclipse.emf.common.notify.Notifier; + +import org.eclipse.emf.common.notify.impl.AdapterFactoryImpl; + +import org.eclipse.emf.ecore.EObject; + +/** + * + * The Adapter Factory for the model. + * It provides an adapter createXXX method for each class of the model. + * + * @see com.ibm.wala.ecore.java.callGraph.CallGraphPackage + * @generated + */ +public class CallGraphAdapterFactory extends AdapterFactoryImpl { + /** + * The cached model package. + * + * + * @generated + */ + protected static CallGraphPackage modelPackage; + + /** + * Creates an instance of the adapter factory. + * + * + * @generated + */ + public CallGraphAdapterFactory() { + if (modelPackage == null) { + modelPackage = CallGraphPackage.eINSTANCE; + } + } + + /** + * Returns whether this factory is applicable for the type of the object. + * + * This implementation returns true if the object is either the model's package or is an instance object of the model. + * + * @return whether this factory is applicable for the type of the object. + * @generated + */ + public boolean isFactoryForType(Object object) { + if (object == modelPackage) { + return true; + } + if (object instanceof EObject) { + return ((EObject)object).eClass().getEPackage() == modelPackage; + } + return false; + } + + /** + * The switch the delegates to the createXXX methods. + * + * + * @generated + */ + protected CallGraphSwitch modelSwitch = + new CallGraphSwitch() { + public Object caseECallGraph(ECallGraph object) { + return createECallGraphAdapter(); + } + public Object caseEGraph(EGraph object) { + return createEGraphAdapter(); + } + public Object defaultCase(EObject object) { + return createEObjectAdapter(); + } + }; + + /** + * Creates an adapter for the target. + * + * + * @param target the object to adapt. + * @return the adapter for the target. + * @generated + */ + public Adapter createAdapter(Notifier target) { + return (Adapter)modelSwitch.doSwitch((EObject)target); + } + + + /** + * Creates a new adapter for an object of class '{@link com.ibm.wala.ecore.java.callGraph.ECallGraph ECall Graph}'. + * + * This default implementation returns null so that we can easily ignore cases; + * it's useful to ignore a case when inheritance will catch all the cases anyway. + * + * @return the new adapter. + * @see com.ibm.wala.ecore.java.callGraph.ECallGraph + * @generated + */ + public Adapter createECallGraphAdapter() { + return null; + } + + /** + * Creates a new adapter for an object of class '{@link com.ibm.wala.ecore.graph.EGraph EGraph}'. + * + * This default implementation returns null so that we can easily ignore cases; + * it's useful to ignore a case when inheritance will catch all the cases anyway. + * + * @return the new adapter. + * @see com.ibm.wala.ecore.graph.EGraph + * @generated + */ + public Adapter createEGraphAdapter() { + return null; + } + + /** + * Creates a new adapter for the default case. + * + * This default implementation returns null. + * + * @return the new adapter. + * @generated + */ + public Adapter createEObjectAdapter() { + return null; + } + +} //CallGraphAdapterFactory diff --git a/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/callGraph/util/CallGraphSwitch.java b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/callGraph/util/CallGraphSwitch.java new file mode 100644 index 000000000..86f8048ce --- /dev/null +++ b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/callGraph/util/CallGraphSwitch.java @@ -0,0 +1,148 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java.callGraph.util; + +import com.ibm.wala.ecore.graph.EGraph; + +import com.ibm.wala.ecore.java.callGraph.*; + +import java.util.List; + +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EObject; + +/** + * + * The Switch for the model's inheritance hierarchy. + * It supports the call {@link #doSwitch(EObject) doSwitch(object)} + * to invoke the caseXXX method for each class of the model, + * starting with the actual class of the object + * and proceeding up the inheritance hierarchy + * until a non-null result is returned, + * which is the result of the switch. + * + * @see com.ibm.wala.ecore.java.callGraph.CallGraphPackage + * @generated + */ +public class CallGraphSwitch { + /** + * The cached model package + * + * + * @generated + */ + protected static CallGraphPackage modelPackage; + + /** + * Creates an instance of the switch. + * + * + * @generated + */ + public CallGraphSwitch() { + if (modelPackage == null) { + modelPackage = CallGraphPackage.eINSTANCE; + } + } + + /** + * Calls caseXXX for each class of the model until one returns a non null result; it yields that result. + * + * + * @return the first non-null result returned by a caseXXX call. + * @generated + */ + public Object doSwitch(EObject theEObject) { + return doSwitch(theEObject.eClass(), theEObject); + } + + /** + * Calls caseXXX for each class of the model until one returns a non null result; it yields that result. + * + * + * @return the first non-null result returned by a caseXXX call. + * @generated + */ + protected Object doSwitch(EClass theEClass, EObject theEObject) { + if (theEClass.eContainer() == modelPackage) { + return doSwitch(theEClass.getClassifierID(), theEObject); + } + else { + List eSuperTypes = theEClass.getESuperTypes(); + return + eSuperTypes.isEmpty() ? + defaultCase(theEObject) : + doSwitch((EClass)eSuperTypes.get(0), theEObject); + } + } + + /** + * Calls caseXXX for each class of the model until one returns a non null result; it yields that result. + * + * + * @return the first non-null result returned by a caseXXX call. + * @generated + */ + protected Object doSwitch(int classifierID, EObject theEObject) { + switch (classifierID) { + case CallGraphPackage.ECALL_GRAPH: { + ECallGraph eCallGraph = (ECallGraph)theEObject; + Object result = caseECallGraph(eCallGraph); + if (result == null) result = caseEGraph(eCallGraph); + if (result == null) result = defaultCase(theEObject); + return result; + } + default: return defaultCase(theEObject); + } + } + + /** + * Returns the result of interpretting the object as an instance of 'ECall Graph'. + * + * This implementation returns null; + * returning a non-null result will terminate the switch. + * + * @param object the target of the switch. + * @return the result of interpretting the object as an instance of 'ECall Graph'. + * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject) + * @generated + */ + public Object caseECallGraph(ECallGraph object) { + return null; + } + + /** + * Returns the result of interpretting the object as an instance of 'EGraph'. + * + * This implementation returns null; + * returning a non-null result will terminate the switch. + * + * @param object the target of the switch. + * @return the result of interpretting the object as an instance of 'EGraph'. + * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject) + * @generated + */ + public Object caseEGraph(EGraph object) { + return null; + } + + /** + * Returns the result of interpretting the object as an instance of 'EObject'. + * + * This implementation returns null; + * returning a non-null result will terminate the switch, but this is the last case anyway. + * + * @param object the target of the switch. + * @return the result of interpretting the object as an instance of 'EObject'. + * @see #doSwitch(org.eclipse.emf.ecore.EObject) + * @generated + */ + public Object defaultCase(EObject object) { + return null; + } + +} //CallGraphSwitch diff --git a/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/impl/ECallSiteImpl.java b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/impl/ECallSiteImpl.java new file mode 100644 index 000000000..e8c432245 --- /dev/null +++ b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/impl/ECallSiteImpl.java @@ -0,0 +1,290 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java.impl; + +import com.ibm.wala.ecore.common.impl.EObjectWithContainerIdImpl; + +import com.ibm.wala.ecore.java.ECallSite; +import com.ibm.wala.ecore.java.EJavaMethod; +import com.ibm.wala.ecore.java.JavaPackage; + +import org.eclipse.emf.common.notify.Notification; + +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.InternalEObject; + +import org.eclipse.emf.ecore.impl.ENotificationImpl; + +/** + * An implementation of the model object 'ECall Site'. + * + *

                              + * The following features are implemented: + *

                                + *
                              • {@link com.ibm.wala.ecore.java.impl.ECallSiteImpl#getBytecodeIndex Bytecode Index}
                              • + *
                              • {@link com.ibm.wala.ecore.java.impl.ECallSiteImpl#getJavaMethod Java Method}
                              • + *
                              • {@link com.ibm.wala.ecore.java.impl.ECallSiteImpl#getDeclaredTarget Declared Target}
                              • + *
                              + *

                              + * + * @generated + */ +public class ECallSiteImpl extends EObjectWithContainerIdImpl implements ECallSite { + + /** + * The default value of the '{@link #getBytecodeIndex() Bytecode Index}' attribute. + * + * @see #getBytecodeIndex() + * @generated + * @ordered + */ + protected static final int BYTECODE_INDEX_EDEFAULT = 0; + + /** + * The cached value of the '{@link #getBytecodeIndex() Bytecode Index}' attribute. + * + * @see #getBytecodeIndex() + * @generated + * @ordered + */ + protected int bytecodeIndex = BYTECODE_INDEX_EDEFAULT; + + /** + * The cached value of the '{@link #getJavaMethod() Java Method}' reference. + * + * @see #getJavaMethod() + * @generated + * @ordered + */ + protected EJavaMethod javaMethod = null; + + /** + * The cached value of the '{@link #getDeclaredTarget() Declared Target}' reference. + * + * @see #getDeclaredTarget() + * @generated + * @ordered + */ + protected EJavaMethod declaredTarget = null; + + /** + * + * @generated + */ + protected ECallSiteImpl() { + super(); + } + + /** + * + * @generated + */ + protected EClass eStaticClass() { + return JavaPackage.Literals.ECALL_SITE; + } + + /** + * + * @generated + */ + public int getBytecodeIndex() { + return bytecodeIndex; + } + + /** + * + * @generated + */ + public void setBytecodeIndex(int newBytecodeIndex) { + int oldBytecodeIndex = bytecodeIndex; + bytecodeIndex = newBytecodeIndex; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, JavaPackage.ECALL_SITE__BYTECODE_INDEX, oldBytecodeIndex, bytecodeIndex)); + } + + /** + * + * @generated + */ + public EJavaMethod getJavaMethod() { + if (javaMethod != null && javaMethod.eIsProxy()) { + InternalEObject oldJavaMethod = (InternalEObject)javaMethod; + javaMethod = (EJavaMethod)eResolveProxy(oldJavaMethod); + if (javaMethod != oldJavaMethod) { + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.RESOLVE, JavaPackage.ECALL_SITE__JAVA_METHOD, oldJavaMethod, javaMethod)); + } + } + return javaMethod; + } + + /** + * + * @generated + */ + public EJavaMethod basicGetJavaMethod() { + return javaMethod; + } + + /** + * + * @generated + */ + public void setJavaMethod(EJavaMethod newJavaMethod) { + EJavaMethod oldJavaMethod = javaMethod; + javaMethod = newJavaMethod; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, JavaPackage.ECALL_SITE__JAVA_METHOD, oldJavaMethod, javaMethod)); + } + + /** + * + * @generated + */ + public EJavaMethod getDeclaredTarget() { + if (declaredTarget != null && declaredTarget.eIsProxy()) { + InternalEObject oldDeclaredTarget = (InternalEObject)declaredTarget; + declaredTarget = (EJavaMethod)eResolveProxy(oldDeclaredTarget); + if (declaredTarget != oldDeclaredTarget) { + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.RESOLVE, JavaPackage.ECALL_SITE__DECLARED_TARGET, oldDeclaredTarget, declaredTarget)); + } + } + return declaredTarget; + } + + /** + * + * @generated + */ + public EJavaMethod basicGetDeclaredTarget() { + return declaredTarget; + } + + /** + * + * @generated + */ + public void setDeclaredTarget(EJavaMethod newDeclaredTarget) { + EJavaMethod oldDeclaredTarget = declaredTarget; + declaredTarget = newDeclaredTarget; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, JavaPackage.ECALL_SITE__DECLARED_TARGET, oldDeclaredTarget, declaredTarget)); + } + + /** + * + * @generated + */ + public Object eGet(int featureID, boolean resolve, boolean coreType) { + switch (featureID) { + case JavaPackage.ECALL_SITE__BYTECODE_INDEX: + return new Integer(getBytecodeIndex()); + case JavaPackage.ECALL_SITE__JAVA_METHOD: + if (resolve) return getJavaMethod(); + return basicGetJavaMethod(); + case JavaPackage.ECALL_SITE__DECLARED_TARGET: + if (resolve) return getDeclaredTarget(); + return basicGetDeclaredTarget(); + } + return super.eGet(featureID, resolve, coreType); + } + + /** + * + * @generated + */ + public void eSet(int featureID, Object newValue) { + switch (featureID) { + case JavaPackage.ECALL_SITE__BYTECODE_INDEX: + setBytecodeIndex(((Integer)newValue).intValue()); + return; + case JavaPackage.ECALL_SITE__JAVA_METHOD: + setJavaMethod((EJavaMethod)newValue); + return; + case JavaPackage.ECALL_SITE__DECLARED_TARGET: + setDeclaredTarget((EJavaMethod)newValue); + return; + } + super.eSet(featureID, newValue); + } + + /** + * + * @generated + */ + public void eUnset(int featureID) { + switch (featureID) { + case JavaPackage.ECALL_SITE__BYTECODE_INDEX: + setBytecodeIndex(BYTECODE_INDEX_EDEFAULT); + return; + case JavaPackage.ECALL_SITE__JAVA_METHOD: + setJavaMethod((EJavaMethod)null); + return; + case JavaPackage.ECALL_SITE__DECLARED_TARGET: + setDeclaredTarget((EJavaMethod)null); + return; + } + super.eUnset(featureID); + } + + /** + * + * @generated + */ + public boolean eIsSet(int featureID) { + switch (featureID) { + case JavaPackage.ECALL_SITE__BYTECODE_INDEX: + return bytecodeIndex != BYTECODE_INDEX_EDEFAULT; + case JavaPackage.ECALL_SITE__JAVA_METHOD: + return javaMethod != null; + case JavaPackage.ECALL_SITE__DECLARED_TARGET: + return declaredTarget != null; + } + return super.eIsSet(featureID); + } + + /** + * + * @generated + */ + public String toString() { + if (eIsProxy()) return super.toString(); + + StringBuffer result = new StringBuffer(super.toString()); + result.append(" (bytecodeIndex: "); + result.append(bytecodeIndex); + result.append(')'); + return result.toString(); + } + + public boolean equals(Object obj) { + if (getClass().equals(obj.getClass())) { + ECallSiteImpl other = (ECallSiteImpl) obj; + if (bytecodeIndex != other.bytecodeIndex) { + return false; + } + if (!javaMethod.equals(other.javaMethod)) { + return false; + } + if (declaredTarget == null) { + return declaredTarget == null; + } + return declaredTarget.equals(other.declaredTarget); + } else { + return false; + } + + } + + public int hashCode() { + int result = bytecodeIndex + javaMethod.hashCode() * 1013; + result = (declaredTarget == null) ? result : result + 281*declaredTarget.hashCode(); + return result; + } + +} // ECallSiteImpl diff --git a/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/impl/EClassHierarchyImpl.java b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/impl/EClassHierarchyImpl.java new file mode 100644 index 000000000..3eefdc5c8 --- /dev/null +++ b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/impl/EClassHierarchyImpl.java @@ -0,0 +1,44 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java.impl; + +import com.ibm.wala.ecore.graph.impl.ETreeImpl; + +import com.ibm.wala.ecore.java.EClassHierarchy; +import com.ibm.wala.ecore.java.JavaPackage; + +import org.eclipse.emf.ecore.EClass; + +/** + * + * An implementation of the model object 'EClass Hierarchy'. + * + *

                              + *

                              + * + * @generated + */ +public class EClassHierarchyImpl extends ETreeImpl implements EClassHierarchy { + /** + * + * + * @generated + */ + protected EClassHierarchyImpl() { + super(); + } + + /** + * + * + * @generated + */ + protected EClass eStaticClass() { + return JavaPackage.Literals.ECLASS_HIERARCHY; + } + +} //EClassHierarchyImpl \ No newline at end of file diff --git a/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/impl/EInterfaceHierarchyImpl.java b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/impl/EInterfaceHierarchyImpl.java new file mode 100644 index 000000000..77ea15981 --- /dev/null +++ b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/impl/EInterfaceHierarchyImpl.java @@ -0,0 +1,44 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java.impl; + +import com.ibm.wala.ecore.graph.impl.EGraphImpl; + +import com.ibm.wala.ecore.java.EInterfaceHierarchy; +import com.ibm.wala.ecore.java.JavaPackage; + +import org.eclipse.emf.ecore.EClass; + +/** + * + * An implementation of the model object 'EInterface Hierarchy'. + * + *

                              + *

                              + * + * @generated + */ +public class EInterfaceHierarchyImpl extends EGraphImpl implements EInterfaceHierarchy { + /** + * + * + * @generated + */ + protected EInterfaceHierarchyImpl() { + super(); + } + + /** + * + * + * @generated + */ + protected EClass eStaticClass() { + return JavaPackage.Literals.EINTERFACE_HIERARCHY; + } + +} //EInterfaceHierarchyImpl \ No newline at end of file diff --git a/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/impl/EJavaClassImpl.java b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/impl/EJavaClassImpl.java new file mode 100644 index 000000000..5e2b88ab1 --- /dev/null +++ b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/impl/EJavaClassImpl.java @@ -0,0 +1,221 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java.impl; + +import com.ibm.wala.ecore.common.impl.EObjectWithContainerIdImpl; + +import com.ibm.wala.ecore.java.EClassLoaderName; +import com.ibm.wala.ecore.java.EJavaClass; +import com.ibm.wala.ecore.java.JavaPackage; + +import org.eclipse.emf.common.notify.Notification; + +import org.eclipse.emf.ecore.EClass; + +import org.eclipse.emf.ecore.impl.ENotificationImpl; + +/** + * + * An implementation of the model object 'EJava Class'. + * + *

                              + * The following features are implemented: + *

                                + *
                              • {@link com.ibm.wala.ecore.java.impl.EJavaClassImpl#getClassName Class Name}
                              • + *
                              • {@link com.ibm.wala.ecore.java.impl.EJavaClassImpl#getLoader Loader}
                              • + *
                              + *

                              + * + * @generated + */ +public class EJavaClassImpl extends EObjectWithContainerIdImpl implements EJavaClass { + /** + * The default value of the '{@link #getClassName() Class Name}' attribute. + * + * + * @see #getClassName() + * @generated + * @ordered + */ + protected static final String CLASS_NAME_EDEFAULT = null; + + /** + * The cached value of the '{@link #getClassName() Class Name}' attribute. + * + * + * @see #getClassName() + * @generated + * @ordered + */ + protected String className = CLASS_NAME_EDEFAULT; + + /** + * The default value of the '{@link #getLoader() Loader}' attribute. + * + * + * @see #getLoader() + * @generated + * @ordered + */ + protected static final EClassLoaderName LOADER_EDEFAULT = EClassLoaderName.APPLICATION_LITERAL; + + /** + * The cached value of the '{@link #getLoader() Loader}' attribute. + * + * + * @see #getLoader() + * @generated + * @ordered + */ + protected EClassLoaderName loader = LOADER_EDEFAULT; + + /** + * + * + * @generated + */ + protected EJavaClassImpl() { + super(); + } + + /** + * + * + * @generated + */ + protected EClass eStaticClass() { + return JavaPackage.Literals.EJAVA_CLASS; + } + + /** + * + * + * @generated + */ + public String getClassName() { + return className; + } + + /** + * + * + * @generated + */ + public void setClassName(String newClassName) { + String oldClassName = className; + className = newClassName; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, JavaPackage.EJAVA_CLASS__CLASS_NAME, oldClassName, className)); + } + + /** + * + * + * @generated + */ + public EClassLoaderName getLoader() { + return loader; + } + + /** + * + * + * @generated + */ + public void setLoader(EClassLoaderName newLoader) { + EClassLoaderName oldLoader = loader; + loader = newLoader == null ? LOADER_EDEFAULT : newLoader; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, JavaPackage.EJAVA_CLASS__LOADER, oldLoader, loader)); + } + + /** + * + * + * @generated + */ + public Object eGet(int featureID, boolean resolve, boolean coreType) { + switch (featureID) { + case JavaPackage.EJAVA_CLASS__CLASS_NAME: + return getClassName(); + case JavaPackage.EJAVA_CLASS__LOADER: + return getLoader(); + } + return super.eGet(featureID, resolve, coreType); + } + + /** + * + * + * @generated + */ + public void eSet(int featureID, Object newValue) { + switch (featureID) { + case JavaPackage.EJAVA_CLASS__CLASS_NAME: + setClassName((String)newValue); + return; + case JavaPackage.EJAVA_CLASS__LOADER: + setLoader((EClassLoaderName)newValue); + return; + } + super.eSet(featureID, newValue); + } + + /** + * + * + * @generated + */ + public void eUnset(int featureID) { + switch (featureID) { + case JavaPackage.EJAVA_CLASS__CLASS_NAME: + setClassName(CLASS_NAME_EDEFAULT); + return; + case JavaPackage.EJAVA_CLASS__LOADER: + setLoader(LOADER_EDEFAULT); + return; + } + super.eUnset(featureID); + } + + /** + * + * + * @generated + */ + public boolean eIsSet(int featureID) { + switch (featureID) { + case JavaPackage.EJAVA_CLASS__CLASS_NAME: + return CLASS_NAME_EDEFAULT == null ? className != null : !CLASS_NAME_EDEFAULT.equals(className); + case JavaPackage.EJAVA_CLASS__LOADER: + return loader != LOADER_EDEFAULT; + } + return super.eIsSet(featureID); + } + + /** + * + * + */ + public String toString() { + return className; + } + + public boolean equals(Object obj) { + if (getClass().equals(obj.getClass())) { + EJavaClassImpl other = (EJavaClassImpl)obj; + return loader.equals(other.loader) && className.equals(other.className); + } else { + return false; + } + } + + public int hashCode() { + return loader.hashCode() + 93 * className.hashCode(); + } + +} //EJavaClassImpl \ No newline at end of file diff --git a/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/impl/EJavaMethodImpl.java b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/impl/EJavaMethodImpl.java new file mode 100644 index 000000000..239144109 --- /dev/null +++ b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/impl/EJavaMethodImpl.java @@ -0,0 +1,330 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java.impl; + +import com.ibm.wala.ecore.common.impl.EObjectWithContainerIdImpl; + +import com.ibm.wala.ecore.java.EJavaClass; +import com.ibm.wala.ecore.java.EJavaMethod; +import com.ibm.wala.ecore.java.JavaPackage; + +import org.eclipse.emf.common.notify.Notification; + +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.InternalEObject; + +import org.eclipse.emf.ecore.impl.ENotificationImpl; + +/** + * + * An implementation of the model object 'EJava Method'. + * + *

                              + * The following features are implemented: + *

                                + *
                              • {@link com.ibm.wala.ecore.java.impl.EJavaMethodImpl#getMethodName Method Name}
                              • + *
                              • {@link com.ibm.wala.ecore.java.impl.EJavaMethodImpl#getDescriptor Descriptor}
                              • + *
                              • {@link com.ibm.wala.ecore.java.impl.EJavaMethodImpl#getJavaClass Java Class}
                              • + *
                              • {@link com.ibm.wala.ecore.java.impl.EJavaMethodImpl#getSignature Signature}
                              • + *
                              + *

                              + * + * @generated + */ +public class EJavaMethodImpl extends EObjectWithContainerIdImpl implements EJavaMethod { + + + /** + * The default value of the '{@link #getMethodName() Method Name}' attribute. + * + * + * @see #getMethodName() + * @generated + * @ordered + */ + protected static final String METHOD_NAME_EDEFAULT = null; + + /** + * The cached value of the '{@link #getMethodName() Method Name}' attribute. + * + * + * @see #getMethodName() + * @generated + * @ordered + */ + protected String methodName = METHOD_NAME_EDEFAULT; + + /** + * The default value of the '{@link #getDescriptor() Descriptor}' attribute. + * + * + * @see #getDescriptor() + * @generated + * @ordered + */ + protected static final String DESCRIPTOR_EDEFAULT = null; + + /** + * The cached value of the '{@link #getDescriptor() Descriptor}' attribute. + * + * + * @see #getDescriptor() + * @generated + * @ordered + */ + protected String descriptor = DESCRIPTOR_EDEFAULT; + + /** + * The cached value of the '{@link #getJavaClass() Java Class}' reference. + * + * + * @see #getJavaClass() + * @generated + * @ordered + */ + protected EJavaClass javaClass = null; + + /** + * The default value of the '{@link #getSignature() Signature}' attribute. + * + * + * @see #getSignature() + * @generated + * @ordered + */ + protected static final String SIGNATURE_EDEFAULT = null; + + /** + * + * + * @generated + */ + protected EJavaMethodImpl() { + super(); + } + + /** + * + * + * @generated + */ + protected EClass eStaticClass() { + return JavaPackage.Literals.EJAVA_METHOD; + } + + /** + * + * + * @generated + */ + public String getMethodName() { + return methodName; + } + + /** + * + * + * @generated + */ + public void setMethodName(String newMethodName) { + String oldMethodName = methodName; + methodName = newMethodName; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, JavaPackage.EJAVA_METHOD__METHOD_NAME, oldMethodName, methodName)); + } + + /** + * + * + * @generated + */ + public String getDescriptor() { + return descriptor; + } + + /** + * + * + * @generated + */ + public void setDescriptor(String newDescriptor) { + String oldDescriptor = descriptor; + descriptor = newDescriptor; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, JavaPackage.EJAVA_METHOD__DESCRIPTOR, oldDescriptor, descriptor)); + } + + /** + * + * + * @generated + */ + public EJavaClass getJavaClass() { + if (javaClass != null && javaClass.eIsProxy()) { + InternalEObject oldJavaClass = (InternalEObject)javaClass; + javaClass = (EJavaClass)eResolveProxy(oldJavaClass); + if (javaClass != oldJavaClass) { + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.RESOLVE, JavaPackage.EJAVA_METHOD__JAVA_CLASS, oldJavaClass, javaClass)); + } + } + return javaClass; + } + + /** + * + * + * @generated + */ + public EJavaClass basicGetJavaClass() { + return javaClass; + } + + /** + * + * + * @generated + */ + public void setJavaClass(EJavaClass newJavaClass) { + EJavaClass oldJavaClass = javaClass; + javaClass = newJavaClass; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, JavaPackage.EJAVA_METHOD__JAVA_CLASS, oldJavaClass, javaClass)); + } + + /** + * + * + * @generated + */ + public String getSignature() { + // TODO: implement this method to return the 'Signature' attribute + // Ensure that you remove @generated or mark it @generated NOT + throw new UnsupportedOperationException(); + } + + /** + * + * + * @generated + */ + public boolean isClinit() { + // TODO: implement this method + // Ensure that you remove @generated or mark it @generated NOT + throw new UnsupportedOperationException(); + } + + /** + * + * + * @generated + */ + public Object eGet(int featureID, boolean resolve, boolean coreType) { + switch (featureID) { + case JavaPackage.EJAVA_METHOD__METHOD_NAME: + return getMethodName(); + case JavaPackage.EJAVA_METHOD__DESCRIPTOR: + return getDescriptor(); + case JavaPackage.EJAVA_METHOD__JAVA_CLASS: + if (resolve) return getJavaClass(); + return basicGetJavaClass(); + case JavaPackage.EJAVA_METHOD__SIGNATURE: + return getSignature(); + } + return super.eGet(featureID, resolve, coreType); + } + + /** + * + * + * @generated + */ + public void eSet(int featureID, Object newValue) { + switch (featureID) { + case JavaPackage.EJAVA_METHOD__METHOD_NAME: + setMethodName((String)newValue); + return; + case JavaPackage.EJAVA_METHOD__DESCRIPTOR: + setDescriptor((String)newValue); + return; + case JavaPackage.EJAVA_METHOD__JAVA_CLASS: + setJavaClass((EJavaClass)newValue); + return; + } + super.eSet(featureID, newValue); + } + + /** + * + * + * @generated + */ + public void eUnset(int featureID) { + switch (featureID) { + case JavaPackage.EJAVA_METHOD__METHOD_NAME: + setMethodName(METHOD_NAME_EDEFAULT); + return; + case JavaPackage.EJAVA_METHOD__DESCRIPTOR: + setDescriptor(DESCRIPTOR_EDEFAULT); + return; + case JavaPackage.EJAVA_METHOD__JAVA_CLASS: + setJavaClass((EJavaClass)null); + return; + } + super.eUnset(featureID); + } + + /** + * + * + * @generated + */ + public boolean eIsSet(int featureID) { + switch (featureID) { + case JavaPackage.EJAVA_METHOD__METHOD_NAME: + return METHOD_NAME_EDEFAULT == null ? methodName != null : !METHOD_NAME_EDEFAULT.equals(methodName); + case JavaPackage.EJAVA_METHOD__DESCRIPTOR: + return DESCRIPTOR_EDEFAULT == null ? descriptor != null : !DESCRIPTOR_EDEFAULT.equals(descriptor); + case JavaPackage.EJAVA_METHOD__JAVA_CLASS: + return javaClass != null; + case JavaPackage.EJAVA_METHOD__SIGNATURE: + return SIGNATURE_EDEFAULT == null ? getSignature() != null : !SIGNATURE_EDEFAULT.equals(getSignature()); + } + return super.eIsSet(featureID); + } + + /** + * + * + * @generated + */ + public String toString() { + if (eIsProxy()) return super.toString(); + + StringBuffer result = new StringBuffer(super.toString()); + result.append(" (methodName: "); + result.append(methodName); + result.append(", descriptor: "); + result.append(descriptor); + result.append(')'); + return result.toString(); + } + + public boolean equals(Object obj) { + if (getClass().equals(obj.getClass())) { + EJavaMethodImpl other = (EJavaMethodImpl)obj; + return descriptor.equals(other.descriptor) && javaClass.equals(other.javaClass) && methodName.equals(other.methodName); + } else { + return false; + } + } + + public int hashCode() { + return descriptor.hashCode() + 157 * javaClass.hashCode() + 1439 * methodName.hashCode(); + } + +} //EJavaMethodImpl \ No newline at end of file diff --git a/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/impl/ETypeHierarchyImpl.java b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/impl/ETypeHierarchyImpl.java new file mode 100644 index 000000000..780bb023b --- /dev/null +++ b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/impl/ETypeHierarchyImpl.java @@ -0,0 +1,309 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java.impl; + +import com.ibm.wala.ecore.common.ERelation; + +import com.ibm.wala.ecore.java.EClassHierarchy; +import com.ibm.wala.ecore.java.EInterfaceHierarchy; +import com.ibm.wala.ecore.java.ETypeHierarchy; +import com.ibm.wala.ecore.java.JavaPackage; + +import org.eclipse.emf.common.notify.Notification; +import org.eclipse.emf.common.notify.NotificationChain; + +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.InternalEObject; + +import org.eclipse.emf.ecore.impl.ENotificationImpl; +import org.eclipse.emf.ecore.impl.EObjectImpl; + +/** + * + * An implementation of the model object 'EType Hierarchy'. + * + *

                              + * The following features are implemented: + *

                                + *
                              • {@link com.ibm.wala.ecore.java.impl.ETypeHierarchyImpl#getClasses Classes}
                              • + *
                              • {@link com.ibm.wala.ecore.java.impl.ETypeHierarchyImpl#getInterfaces Interfaces}
                              • + *
                              • {@link com.ibm.wala.ecore.java.impl.ETypeHierarchyImpl#getImplements Implements}
                              • + *
                              + *

                              + * + * @generated + */ +public class ETypeHierarchyImpl extends EObjectImpl implements ETypeHierarchy { + /** + * The cached value of the '{@link #getClasses() Classes}' containment reference. + * + * + * @see #getClasses() + * @generated + * @ordered + */ + protected EClassHierarchy classes = null; + + /** + * The cached value of the '{@link #getInterfaces() Interfaces}' containment reference. + * + * + * @see #getInterfaces() + * @generated + * @ordered + */ + protected EInterfaceHierarchy interfaces = null; + + /** + * The cached value of the '{@link #getImplements() Implements}' containment reference. + * + * + * @see #getImplements() + * @generated + * @ordered + */ + protected ERelation implements_ = null; + + /** + * + * + * @generated + */ + protected ETypeHierarchyImpl() { + super(); + } + + /** + * + * + * @generated + */ + protected EClass eStaticClass() { + return JavaPackage.Literals.ETYPE_HIERARCHY; + } + + /** + * + * + * @generated + */ + public EClassHierarchy getClasses() { + return classes; + } + + /** + * + * + * @generated + */ + public NotificationChain basicSetClasses(EClassHierarchy newClasses, NotificationChain msgs) { + EClassHierarchy oldClasses = classes; + classes = newClasses; + if (eNotificationRequired()) { + ENotificationImpl notification = new ENotificationImpl(this, Notification.SET, JavaPackage.ETYPE_HIERARCHY__CLASSES, oldClasses, newClasses); + if (msgs == null) msgs = notification; else msgs.add(notification); + } + return msgs; + } + + /** + * + * + * @generated + */ + public void setClasses(EClassHierarchy newClasses) { + if (newClasses != classes) { + NotificationChain msgs = null; + if (classes != null) + msgs = ((InternalEObject)classes).eInverseRemove(this, EOPPOSITE_FEATURE_BASE - JavaPackage.ETYPE_HIERARCHY__CLASSES, null, msgs); + if (newClasses != null) + msgs = ((InternalEObject)newClasses).eInverseAdd(this, EOPPOSITE_FEATURE_BASE - JavaPackage.ETYPE_HIERARCHY__CLASSES, null, msgs); + msgs = basicSetClasses(newClasses, msgs); + if (msgs != null) msgs.dispatch(); + } + else if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, JavaPackage.ETYPE_HIERARCHY__CLASSES, newClasses, newClasses)); + } + + /** + * + * + * @generated + */ + public EInterfaceHierarchy getInterfaces() { + return interfaces; + } + + /** + * + * + * @generated + */ + public NotificationChain basicSetInterfaces(EInterfaceHierarchy newInterfaces, NotificationChain msgs) { + EInterfaceHierarchy oldInterfaces = interfaces; + interfaces = newInterfaces; + if (eNotificationRequired()) { + ENotificationImpl notification = new ENotificationImpl(this, Notification.SET, JavaPackage.ETYPE_HIERARCHY__INTERFACES, oldInterfaces, newInterfaces); + if (msgs == null) msgs = notification; else msgs.add(notification); + } + return msgs; + } + + /** + * + * + * @generated + */ + public void setInterfaces(EInterfaceHierarchy newInterfaces) { + if (newInterfaces != interfaces) { + NotificationChain msgs = null; + if (interfaces != null) + msgs = ((InternalEObject)interfaces).eInverseRemove(this, EOPPOSITE_FEATURE_BASE - JavaPackage.ETYPE_HIERARCHY__INTERFACES, null, msgs); + if (newInterfaces != null) + msgs = ((InternalEObject)newInterfaces).eInverseAdd(this, EOPPOSITE_FEATURE_BASE - JavaPackage.ETYPE_HIERARCHY__INTERFACES, null, msgs); + msgs = basicSetInterfaces(newInterfaces, msgs); + if (msgs != null) msgs.dispatch(); + } + else if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, JavaPackage.ETYPE_HIERARCHY__INTERFACES, newInterfaces, newInterfaces)); + } + + /** + * + * + * @generated + */ + public ERelation getImplements() { + return implements_; + } + + /** + * + * + * @generated + */ + public NotificationChain basicSetImplements(ERelation newImplements, NotificationChain msgs) { + ERelation oldImplements = implements_; + implements_ = newImplements; + if (eNotificationRequired()) { + ENotificationImpl notification = new ENotificationImpl(this, Notification.SET, JavaPackage.ETYPE_HIERARCHY__IMPLEMENTS, oldImplements, newImplements); + if (msgs == null) msgs = notification; else msgs.add(notification); + } + return msgs; + } + + /** + * + * + * @generated + */ + public void setImplements(ERelation newImplements) { + if (newImplements != implements_) { + NotificationChain msgs = null; + if (implements_ != null) + msgs = ((InternalEObject)implements_).eInverseRemove(this, EOPPOSITE_FEATURE_BASE - JavaPackage.ETYPE_HIERARCHY__IMPLEMENTS, null, msgs); + if (newImplements != null) + msgs = ((InternalEObject)newImplements).eInverseAdd(this, EOPPOSITE_FEATURE_BASE - JavaPackage.ETYPE_HIERARCHY__IMPLEMENTS, null, msgs); + msgs = basicSetImplements(newImplements, msgs); + if (msgs != null) msgs.dispatch(); + } + else if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, JavaPackage.ETYPE_HIERARCHY__IMPLEMENTS, newImplements, newImplements)); + } + + /** + * + * + * @generated + */ + public NotificationChain eInverseRemove(InternalEObject otherEnd, int featureID, NotificationChain msgs) { + switch (featureID) { + case JavaPackage.ETYPE_HIERARCHY__CLASSES: + return basicSetClasses(null, msgs); + case JavaPackage.ETYPE_HIERARCHY__INTERFACES: + return basicSetInterfaces(null, msgs); + case JavaPackage.ETYPE_HIERARCHY__IMPLEMENTS: + return basicSetImplements(null, msgs); + } + return super.eInverseRemove(otherEnd, featureID, msgs); + } + + /** + * + * + * @generated + */ + public Object eGet(int featureID, boolean resolve, boolean coreType) { + switch (featureID) { + case JavaPackage.ETYPE_HIERARCHY__CLASSES: + return getClasses(); + case JavaPackage.ETYPE_HIERARCHY__INTERFACES: + return getInterfaces(); + case JavaPackage.ETYPE_HIERARCHY__IMPLEMENTS: + return getImplements(); + } + return super.eGet(featureID, resolve, coreType); + } + + /** + * + * + * @generated + */ + public void eSet(int featureID, Object newValue) { + switch (featureID) { + case JavaPackage.ETYPE_HIERARCHY__CLASSES: + setClasses((EClassHierarchy)newValue); + return; + case JavaPackage.ETYPE_HIERARCHY__INTERFACES: + setInterfaces((EInterfaceHierarchy)newValue); + return; + case JavaPackage.ETYPE_HIERARCHY__IMPLEMENTS: + setImplements((ERelation)newValue); + return; + } + super.eSet(featureID, newValue); + } + + /** + * + * + * @generated + */ + public void eUnset(int featureID) { + switch (featureID) { + case JavaPackage.ETYPE_HIERARCHY__CLASSES: + setClasses((EClassHierarchy)null); + return; + case JavaPackage.ETYPE_HIERARCHY__INTERFACES: + setInterfaces((EInterfaceHierarchy)null); + return; + case JavaPackage.ETYPE_HIERARCHY__IMPLEMENTS: + setImplements((ERelation)null); + return; + } + super.eUnset(featureID); + } + + /** + * + * + * @generated + */ + public boolean eIsSet(int featureID) { + switch (featureID) { + case JavaPackage.ETYPE_HIERARCHY__CLASSES: + return classes != null; + case JavaPackage.ETYPE_HIERARCHY__INTERFACES: + return interfaces != null; + case JavaPackage.ETYPE_HIERARCHY__IMPLEMENTS: + return implements_ != null; + } + return super.eIsSet(featureID); + } + +} //ETypeHierarchyImpl \ No newline at end of file diff --git a/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/impl/JavaFactoryImpl.java b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/impl/JavaFactoryImpl.java new file mode 100644 index 000000000..c590f0a06 --- /dev/null +++ b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/impl/JavaFactoryImpl.java @@ -0,0 +1,201 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java.impl; + +import com.ibm.wala.ecore.java.*; + +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EDataType; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EPackage; + +import org.eclipse.emf.ecore.impl.EFactoryImpl; + +import org.eclipse.emf.ecore.plugin.EcorePlugin; + +/** + * + * An implementation of the model Factory. + * + * @generated + */ +public class JavaFactoryImpl extends EFactoryImpl implements JavaFactory { + /** + * Creates the default factory implementation. + * + * + * @generated + */ + public static JavaFactory init() { + try { + JavaFactory theJavaFactory = (JavaFactory)EPackage.Registry.INSTANCE.getEFactory("http:///com/ibm/wala/wala.ecore.java"); + if (theJavaFactory != null) { + return theJavaFactory; + } + } + catch (Exception exception) { + EcorePlugin.INSTANCE.log(exception); + } + return new JavaFactoryImpl(); + } + + /** + * Creates an instance of the factory. + * + * + * @generated + */ + public JavaFactoryImpl() { + super(); + } + + /** + * + * + * @generated + */ + public EObject create(EClass eClass) { + switch (eClass.getClassifierID()) { + case JavaPackage.EJAVA_CLASS: return createEJavaClass(); + case JavaPackage.EJAVA_METHOD: return createEJavaMethod(); + case JavaPackage.ECALL_SITE: return createECallSite(); + case JavaPackage.ECLASS_HIERARCHY: return createEClassHierarchy(); + case JavaPackage.EINTERFACE_HIERARCHY: return createEInterfaceHierarchy(); + case JavaPackage.ETYPE_HIERARCHY: return createETypeHierarchy(); + default: + throw new IllegalArgumentException("The class '" + eClass.getName() + "' is not a valid classifier"); + } + } + + /** + * + * + * @generated + */ + public Object createFromString(EDataType eDataType, String initialValue) { + switch (eDataType.getClassifierID()) { + case JavaPackage.ECLASS_LOADER_NAME: + return createEClassLoaderNameFromString(eDataType, initialValue); + default: + throw new IllegalArgumentException("The datatype '" + eDataType.getName() + "' is not a valid classifier"); + } + } + + /** + * + * + * @generated + */ + public String convertToString(EDataType eDataType, Object instanceValue) { + switch (eDataType.getClassifierID()) { + case JavaPackage.ECLASS_LOADER_NAME: + return convertEClassLoaderNameToString(eDataType, instanceValue); + default: + throw new IllegalArgumentException("The datatype '" + eDataType.getName() + "' is not a valid classifier"); + } + } + + /** + * + * + * @generated + */ + public EJavaClass createEJavaClass() { + EJavaClassImpl eJavaClass = new EJavaClassImpl(); + return eJavaClass; + } + + /** + * + * + * @generated + */ + public EJavaMethod createEJavaMethod() { + EJavaMethodImpl eJavaMethod = new EJavaMethodImpl(); + return eJavaMethod; + } + + /** + * + * + * @generated + */ + public ECallSite createECallSite() { + ECallSiteImpl eCallSite = new ECallSiteImpl(); + return eCallSite; + } + + /** + * + * + * @generated + */ + public EClassHierarchy createEClassHierarchy() { + EClassHierarchyImpl eClassHierarchy = new EClassHierarchyImpl(); + return eClassHierarchy; + } + + /** + * + * + * @generated + */ + public EInterfaceHierarchy createEInterfaceHierarchy() { + EInterfaceHierarchyImpl eInterfaceHierarchy = new EInterfaceHierarchyImpl(); + return eInterfaceHierarchy; + } + + /** + * + * + * @generated + */ + public ETypeHierarchy createETypeHierarchy() { + ETypeHierarchyImpl eTypeHierarchy = new ETypeHierarchyImpl(); + return eTypeHierarchy; + } + + /** + * + * + * @generated + */ + public EClassLoaderName createEClassLoaderNameFromString(EDataType eDataType, String initialValue) { + EClassLoaderName result = EClassLoaderName.get(initialValue); + if (result == null) throw new IllegalArgumentException("The value '" + initialValue + "' is not a valid enumerator of '" + eDataType.getName() + "'"); + return result; + } + + /** + * + * + * @generated + */ + public String convertEClassLoaderNameToString(EDataType eDataType, Object instanceValue) { + return instanceValue == null ? null : instanceValue.toString(); + } + + /** + * + * + * @generated + */ + public JavaPackage getJavaPackage() { + return (JavaPackage)getEPackage(); + } + + /** + * + * + * @deprecated + * @generated + */ + public static JavaPackage getPackage() { + return JavaPackage.eINSTANCE; + } + +} //JavaFactoryImpl diff --git a/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/impl/JavaPackageImpl.java b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/impl/JavaPackageImpl.java new file mode 100644 index 000000000..979671bd5 --- /dev/null +++ b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/impl/JavaPackageImpl.java @@ -0,0 +1,515 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java.impl; + +import com.ibm.wala.ecore.common.CommonPackage; + +import com.ibm.wala.ecore.common.impl.CommonPackageImpl; + +import com.ibm.wala.ecore.graph.GraphPackage; + +import com.ibm.wala.ecore.graph.impl.GraphPackageImpl; + +import com.ibm.wala.ecore.j2ee.scope.J2EEScopePackage; + +import com.ibm.wala.ecore.j2ee.scope.impl.J2EEScopePackageImpl; + +import com.ibm.wala.ecore.java.ECallSite; +import com.ibm.wala.ecore.java.EClassHierarchy; +import com.ibm.wala.ecore.java.EClassLoaderName; +import com.ibm.wala.ecore.java.EInterfaceHierarchy; +import com.ibm.wala.ecore.java.EJavaClass; +import com.ibm.wala.ecore.java.EJavaMethod; +import com.ibm.wala.ecore.java.ETypeHierarchy; +import com.ibm.wala.ecore.java.JavaFactory; +import com.ibm.wala.ecore.java.JavaPackage; + +import com.ibm.wala.ecore.java.callGraph.CallGraphPackage; + +import com.ibm.wala.ecore.java.callGraph.impl.CallGraphPackageImpl; + +import com.ibm.wala.ecore.java.pointerAnalysis.PointerAnalysisPackage; + +import com.ibm.wala.ecore.java.pointerAnalysis.impl.PointerAnalysisPackageImpl; + +import com.ibm.wala.ecore.java.scope.JavaScopePackage; + +import com.ibm.wala.ecore.java.scope.impl.JavaScopePackageImpl; + +import com.ibm.wala.ecore.perf.PerfPackage; + +import com.ibm.wala.ecore.perf.impl.PerfPackageImpl; + +import com.ibm.wala.ecore.regex.RegexPackage; + +import com.ibm.wala.ecore.regex.impl.RegexPackageImpl; + +import org.eclipse.emf.ecore.EAttribute; +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EEnum; +import org.eclipse.emf.ecore.EPackage; +import org.eclipse.emf.ecore.EReference; + +import org.eclipse.emf.ecore.impl.EPackageImpl; + +/** + * + * An implementation of the model Package. + * + * @generated + */ +public class JavaPackageImpl extends EPackageImpl implements JavaPackage { + /** + * + * + * @generated + */ + private EClass eJavaClassEClass = null; + + /** + * + * + * @generated + */ + private EClass eJavaMethodEClass = null; + + /** + * + * + * @generated + */ + private EClass eCallSiteEClass = null; + + /** + * + * + * @generated + */ + private EClass eClassHierarchyEClass = null; + + /** + * + * + * @generated + */ + private EClass eInterfaceHierarchyEClass = null; + + /** + * + * + * @generated + */ + private EClass eTypeHierarchyEClass = null; + + /** + * + * + * @generated + */ + private EEnum eClassLoaderNameEEnum = null; + + /** + * Creates an instance of the model Package, registered with + * {@link org.eclipse.emf.ecore.EPackage.Registry EPackage.Registry} by the package + * package URI value. + *

                              Note: the correct way to create the package is via the static + * factory method {@link #init init()}, which also performs + * initialization of the package, or returns the registered package, + * if one already exists. + * + * + * @see org.eclipse.emf.ecore.EPackage.Registry + * @see com.ibm.wala.ecore.java.JavaPackage#eNS_URI + * @see #init() + * @generated + */ + private JavaPackageImpl() { + super(eNS_URI, JavaFactory.eINSTANCE); + } + + /** + * + * + * @generated + */ + private static boolean isInited = false; + + /** + * Creates, registers, and initializes the Package for this + * model, and for any others upon which it depends. Simple + * dependencies are satisfied by calling this method on all + * dependent packages before doing anything else. This method drives + * initialization for interdependent packages directly, in parallel + * with this package, itself. + *

                              Of this package and its interdependencies, all packages which + * have not yet been registered by their URI values are first created + * and registered. The packages are then initialized in two steps: + * meta-model objects for all of the packages are created before any + * are initialized, since one package's meta-model objects may refer to + * those of another. + *

                              Invocation of this method will not affect any packages that have + * already been initialized. + * + * + * @see #eNS_URI + * @see #createPackageContents() + * @see #initializePackageContents() + * @generated + */ + public static JavaPackage init() { + if (isInited) return (JavaPackage)EPackage.Registry.INSTANCE.getEPackage(JavaPackage.eNS_URI); + + // Obtain or create and register package + JavaPackageImpl theJavaPackage = (JavaPackageImpl)(EPackage.Registry.INSTANCE.getEPackage(eNS_URI) instanceof JavaPackageImpl ? EPackage.Registry.INSTANCE.getEPackage(eNS_URI) : new JavaPackageImpl()); + + isInited = true; + + // Obtain or create and register interdependencies + GraphPackageImpl theGraphPackage = (GraphPackageImpl)(EPackage.Registry.INSTANCE.getEPackage(GraphPackage.eNS_URI) instanceof GraphPackageImpl ? EPackage.Registry.INSTANCE.getEPackage(GraphPackage.eNS_URI) : GraphPackage.eINSTANCE); + CommonPackageImpl theCommonPackage = (CommonPackageImpl)(EPackage.Registry.INSTANCE.getEPackage(CommonPackage.eNS_URI) instanceof CommonPackageImpl ? EPackage.Registry.INSTANCE.getEPackage(CommonPackage.eNS_URI) : CommonPackage.eINSTANCE); + RegexPackageImpl theRegexPackage = (RegexPackageImpl)(EPackage.Registry.INSTANCE.getEPackage(RegexPackage.eNS_URI) instanceof RegexPackageImpl ? EPackage.Registry.INSTANCE.getEPackage(RegexPackage.eNS_URI) : RegexPackage.eINSTANCE); + PerfPackageImpl thePerfPackage = (PerfPackageImpl)(EPackage.Registry.INSTANCE.getEPackage(PerfPackage.eNS_URI) instanceof PerfPackageImpl ? EPackage.Registry.INSTANCE.getEPackage(PerfPackage.eNS_URI) : PerfPackage.eINSTANCE); + CallGraphPackageImpl theCallGraphPackage = (CallGraphPackageImpl)(EPackage.Registry.INSTANCE.getEPackage(CallGraphPackage.eNS_URI) instanceof CallGraphPackageImpl ? EPackage.Registry.INSTANCE.getEPackage(CallGraphPackage.eNS_URI) : CallGraphPackage.eINSTANCE); + PointerAnalysisPackageImpl thePointerAnalysisPackage = (PointerAnalysisPackageImpl)(EPackage.Registry.INSTANCE.getEPackage(PointerAnalysisPackage.eNS_URI) instanceof PointerAnalysisPackageImpl ? EPackage.Registry.INSTANCE.getEPackage(PointerAnalysisPackage.eNS_URI) : PointerAnalysisPackage.eINSTANCE); + JavaScopePackageImpl theJavaScopePackage = (JavaScopePackageImpl)(EPackage.Registry.INSTANCE.getEPackage(JavaScopePackage.eNS_URI) instanceof JavaScopePackageImpl ? EPackage.Registry.INSTANCE.getEPackage(JavaScopePackage.eNS_URI) : JavaScopePackage.eINSTANCE); + J2EEScopePackageImpl theJ2EEScopePackage = (J2EEScopePackageImpl)(EPackage.Registry.INSTANCE.getEPackage(J2EEScopePackage.eNS_URI) instanceof J2EEScopePackageImpl ? EPackage.Registry.INSTANCE.getEPackage(J2EEScopePackage.eNS_URI) : J2EEScopePackage.eINSTANCE); + + // Create package meta-data objects + theJavaPackage.createPackageContents(); + theGraphPackage.createPackageContents(); + theCommonPackage.createPackageContents(); + theRegexPackage.createPackageContents(); + thePerfPackage.createPackageContents(); + theCallGraphPackage.createPackageContents(); + thePointerAnalysisPackage.createPackageContents(); + theJavaScopePackage.createPackageContents(); + theJ2EEScopePackage.createPackageContents(); + + // Initialize created meta-data + theJavaPackage.initializePackageContents(); + theGraphPackage.initializePackageContents(); + theCommonPackage.initializePackageContents(); + theRegexPackage.initializePackageContents(); + thePerfPackage.initializePackageContents(); + theCallGraphPackage.initializePackageContents(); + thePointerAnalysisPackage.initializePackageContents(); + theJavaScopePackage.initializePackageContents(); + theJ2EEScopePackage.initializePackageContents(); + + // Mark meta-data to indicate it can't be changed + theJavaPackage.freeze(); + + return theJavaPackage; + } + + /** + * + * + * @generated + */ + public EClass getEJavaClass() { + return eJavaClassEClass; + } + + /** + * + * + * @generated + */ + public EAttribute getEJavaClass_ClassName() { + return (EAttribute)eJavaClassEClass.getEStructuralFeatures().get(0); + } + + /** + * + * + * @generated + */ + public EAttribute getEJavaClass_Loader() { + return (EAttribute)eJavaClassEClass.getEStructuralFeatures().get(1); + } + + /** + * + * + * @generated + */ + public EClass getEJavaMethod() { + return eJavaMethodEClass; + } + + /** + * + * + * @generated + */ + public EAttribute getEJavaMethod_MethodName() { + return (EAttribute)eJavaMethodEClass.getEStructuralFeatures().get(0); + } + + /** + * + * + * @generated + */ + public EAttribute getEJavaMethod_Descriptor() { + return (EAttribute)eJavaMethodEClass.getEStructuralFeatures().get(1); + } + + /** + * + * + * @generated + */ + public EReference getEJavaMethod_JavaClass() { + return (EReference)eJavaMethodEClass.getEStructuralFeatures().get(2); + } + + /** + * + * + * @generated + */ + public EAttribute getEJavaMethod_Signature() { + return (EAttribute)eJavaMethodEClass.getEStructuralFeatures().get(3); + } + + /** + * + * + * @generated + */ + public EClass getECallSite() { + return eCallSiteEClass; + } + + /** + * + * + * @generated + */ + public EAttribute getECallSite_BytecodeIndex() { + return (EAttribute)eCallSiteEClass.getEStructuralFeatures().get(0); + } + + /** + * + * + * @generated + */ + public EReference getECallSite_JavaMethod() { + return (EReference)eCallSiteEClass.getEStructuralFeatures().get(1); + } + + /** + * + * + * @generated + */ + public EReference getECallSite_DeclaredTarget() { + return (EReference)eCallSiteEClass.getEStructuralFeatures().get(2); + } + + /** + * + * + * @generated + */ + public EClass getEClassHierarchy() { + return eClassHierarchyEClass; + } + + /** + * + * + * @generated + */ + public EClass getEInterfaceHierarchy() { + return eInterfaceHierarchyEClass; + } + + /** + * + * + * @generated + */ + public EClass getETypeHierarchy() { + return eTypeHierarchyEClass; + } + + /** + * + * + * @generated + */ + public EReference getETypeHierarchy_Classes() { + return (EReference)eTypeHierarchyEClass.getEStructuralFeatures().get(0); + } + + /** + * + * + * @generated + */ + public EReference getETypeHierarchy_Interfaces() { + return (EReference)eTypeHierarchyEClass.getEStructuralFeatures().get(1); + } + + /** + * + * + * @generated + */ + public EReference getETypeHierarchy_Implements() { + return (EReference)eTypeHierarchyEClass.getEStructuralFeatures().get(2); + } + + /** + * + * + * @generated + */ + public EEnum getEClassLoaderName() { + return eClassLoaderNameEEnum; + } + + /** + * + * + * @generated + */ + public JavaFactory getJavaFactory() { + return (JavaFactory)getEFactoryInstance(); + } + + /** + * + * + * @generated + */ + private boolean isCreated = false; + + /** + * Creates the meta-model objects for the package. This method is + * guarded to have no affect on any invocation but its first. + * + * + * @generated + */ + public void createPackageContents() { + if (isCreated) return; + isCreated = true; + + // Create classes and their features + eJavaClassEClass = createEClass(EJAVA_CLASS); + createEAttribute(eJavaClassEClass, EJAVA_CLASS__CLASS_NAME); + createEAttribute(eJavaClassEClass, EJAVA_CLASS__LOADER); + + eJavaMethodEClass = createEClass(EJAVA_METHOD); + createEAttribute(eJavaMethodEClass, EJAVA_METHOD__METHOD_NAME); + createEAttribute(eJavaMethodEClass, EJAVA_METHOD__DESCRIPTOR); + createEReference(eJavaMethodEClass, EJAVA_METHOD__JAVA_CLASS); + createEAttribute(eJavaMethodEClass, EJAVA_METHOD__SIGNATURE); + + eCallSiteEClass = createEClass(ECALL_SITE); + createEAttribute(eCallSiteEClass, ECALL_SITE__BYTECODE_INDEX); + createEReference(eCallSiteEClass, ECALL_SITE__JAVA_METHOD); + createEReference(eCallSiteEClass, ECALL_SITE__DECLARED_TARGET); + + eClassHierarchyEClass = createEClass(ECLASS_HIERARCHY); + + eInterfaceHierarchyEClass = createEClass(EINTERFACE_HIERARCHY); + + eTypeHierarchyEClass = createEClass(ETYPE_HIERARCHY); + createEReference(eTypeHierarchyEClass, ETYPE_HIERARCHY__CLASSES); + createEReference(eTypeHierarchyEClass, ETYPE_HIERARCHY__INTERFACES); + createEReference(eTypeHierarchyEClass, ETYPE_HIERARCHY__IMPLEMENTS); + + // Create enums + eClassLoaderNameEEnum = createEEnum(ECLASS_LOADER_NAME); + } + + /** + * + * + * @generated + */ + private boolean isInitialized = false; + + /** + * Complete the initialization of the package and its meta-model. This + * method is guarded to have no affect on any invocation but its first. + * + * + * @generated + */ + public void initializePackageContents() { + if (isInitialized) return; + isInitialized = true; + + // Initialize package + setName(eNAME); + setNsPrefix(eNS_PREFIX); + setNsURI(eNS_URI); + + // Obtain other dependent packages + CallGraphPackage theCallGraphPackage = (CallGraphPackage)EPackage.Registry.INSTANCE.getEPackage(CallGraphPackage.eNS_URI); + PointerAnalysisPackage thePointerAnalysisPackage = (PointerAnalysisPackage)EPackage.Registry.INSTANCE.getEPackage(PointerAnalysisPackage.eNS_URI); + JavaScopePackage theJavaScopePackage = (JavaScopePackage)EPackage.Registry.INSTANCE.getEPackage(JavaScopePackage.eNS_URI); + CommonPackage theCommonPackage = (CommonPackage)EPackage.Registry.INSTANCE.getEPackage(CommonPackage.eNS_URI); + GraphPackage theGraphPackage = (GraphPackage)EPackage.Registry.INSTANCE.getEPackage(GraphPackage.eNS_URI); + + // Add subpackages + getESubpackages().add(theCallGraphPackage); + getESubpackages().add(thePointerAnalysisPackage); + getESubpackages().add(theJavaScopePackage); + + // Add supertypes to classes + eJavaClassEClass.getESuperTypes().add(theCommonPackage.getEObjectWithContainerId()); + eJavaMethodEClass.getESuperTypes().add(theCommonPackage.getEObjectWithContainerId()); + eCallSiteEClass.getESuperTypes().add(theCommonPackage.getEObjectWithContainerId()); + eClassHierarchyEClass.getESuperTypes().add(theGraphPackage.getETree()); + eInterfaceHierarchyEClass.getESuperTypes().add(theGraphPackage.getEGraph()); + + // Initialize classes and features; add operations and parameters + initEClass(eJavaClassEClass, EJavaClass.class, "EJavaClass", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); + initEAttribute(getEJavaClass_ClassName(), ecorePackage.getEString(), "className", null, 1, 1, EJavaClass.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); + initEAttribute(getEJavaClass_Loader(), this.getEClassLoaderName(), "loader", null, 1, 1, EJavaClass.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); + + initEClass(eJavaMethodEClass, EJavaMethod.class, "EJavaMethod", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); + initEAttribute(getEJavaMethod_MethodName(), ecorePackage.getEString(), "methodName", null, 1, 1, EJavaMethod.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); + initEAttribute(getEJavaMethod_Descriptor(), ecorePackage.getEString(), "descriptor", null, 1, 1, EJavaMethod.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); + initEReference(getEJavaMethod_JavaClass(), this.getEJavaClass(), null, "javaClass", null, 1, 1, EJavaMethod.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_COMPOSITE, IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); + initEAttribute(getEJavaMethod_Signature(), ecorePackage.getEString(), "signature", null, 0, 1, EJavaMethod.class, IS_TRANSIENT, IS_VOLATILE, !IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, IS_UNIQUE, IS_DERIVED, IS_ORDERED); + + addEOperation(eJavaMethodEClass, ecorePackage.getEBoolean(), "isClinit", 0, 1); + + initEClass(eCallSiteEClass, ECallSite.class, "ECallSite", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); + initEAttribute(getECallSite_BytecodeIndex(), ecorePackage.getEInt(), "bytecodeIndex", null, 0, 1, ECallSite.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); + initEReference(getECallSite_JavaMethod(), this.getEJavaMethod(), null, "javaMethod", null, 1, 1, ECallSite.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_COMPOSITE, IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); + initEReference(getECallSite_DeclaredTarget(), this.getEJavaMethod(), null, "declaredTarget", null, 1, 1, ECallSite.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_COMPOSITE, IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); + + initEClass(eClassHierarchyEClass, EClassHierarchy.class, "EClassHierarchy", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); + + initEClass(eInterfaceHierarchyEClass, EInterfaceHierarchy.class, "EInterfaceHierarchy", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); + + initEClass(eTypeHierarchyEClass, ETypeHierarchy.class, "ETypeHierarchy", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); + initEReference(getETypeHierarchy_Classes(), this.getEClassHierarchy(), null, "classes", null, 1, 1, ETypeHierarchy.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, IS_COMPOSITE, !IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); + initEReference(getETypeHierarchy_Interfaces(), this.getEInterfaceHierarchy(), null, "interfaces", null, 1, 1, ETypeHierarchy.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, IS_COMPOSITE, !IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); + initEReference(getETypeHierarchy_Implements(), theCommonPackage.getERelation(), null, "implements", null, 1, 1, ETypeHierarchy.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, IS_COMPOSITE, !IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); + + // Initialize enums and add enum literals + initEEnum(eClassLoaderNameEEnum, EClassLoaderName.class, "EClassLoaderName"); + addEEnumLiteral(eClassLoaderNameEEnum, EClassLoaderName.APPLICATION_LITERAL); + addEEnumLiteral(eClassLoaderNameEEnum, EClassLoaderName.PRIMORDIAL_LITERAL); + addEEnumLiteral(eClassLoaderNameEEnum, EClassLoaderName.EXTENSION_LITERAL); + + // Create resource + createResource(eNS_URI); + } + +} //JavaPackageImpl diff --git a/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/pointerAnalysis/EArrayContents.java b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/pointerAnalysis/EArrayContents.java new file mode 100644 index 000000000..1be7089e9 --- /dev/null +++ b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/pointerAnalysis/EArrayContents.java @@ -0,0 +1,54 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java.pointerAnalysis; + +import com.ibm.wala.ecore.java.EJavaClass; + +/** + * + * A representation of the model object 'EArray Contents'. + * + * + *

                              + * The following features are supported: + *

                                + *
                              • {@link com.ibm.wala.ecore.java.pointerAnalysis.EArrayContents#getJavaClass Java Class}
                              • + *
                              + *

                              + * + * @see com.ibm.wala.ecore.java.pointerAnalysis.PointerAnalysisPackage#getEArrayContents() + * @model + * @generated + */ +public interface EArrayContents extends EPointer { + /** + * Returns the value of the 'Java Class' reference. + * + *

                              + * If the meaning of the 'Java Class' reference isn't clear, + * there really should be more of a description here... + *

                              + * + * @return the value of the 'Java Class' reference. + * @see #setJavaClass(EJavaClass) + * @see com.ibm.wala.ecore.java.pointerAnalysis.PointerAnalysisPackage#getEArrayContents_JavaClass() + * @model required="true" + * @generated + */ + EJavaClass getJavaClass(); + + /** + * Sets the value of the '{@link com.ibm.wala.ecore.java.pointerAnalysis.EArrayContents#getJavaClass Java Class}' reference. + * + * + * @param value the new value of the 'Java Class' reference. + * @see #getJavaClass() + * @generated + */ + void setJavaClass(EJavaClass value); + +} // EArrayContents \ No newline at end of file diff --git a/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/pointerAnalysis/EHeapGraph.java b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/pointerAnalysis/EHeapGraph.java new file mode 100644 index 000000000..f78f7793d --- /dev/null +++ b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/pointerAnalysis/EHeapGraph.java @@ -0,0 +1,22 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java.pointerAnalysis; + +import com.ibm.wala.ecore.graph.EGraph; + +/** + * + * A representation of the model object 'EHeap Graph'. + * + * + * + * @see com.ibm.wala.ecore.java.pointerAnalysis.PointerAnalysisPackage#getEHeapGraph() + * @model + * @generated + */ +public interface EHeapGraph extends EGraph { +} // EHeapGraph \ No newline at end of file diff --git a/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/pointerAnalysis/EInstance.java b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/pointerAnalysis/EInstance.java new file mode 100644 index 000000000..fd4a40154 --- /dev/null +++ b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/pointerAnalysis/EInstance.java @@ -0,0 +1,22 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java.pointerAnalysis; + +import org.eclipse.emf.ecore.EObject; + +/** + * + * A representation of the model object 'EInstance'. + * + * + * + * @see com.ibm.wala.ecore.java.pointerAnalysis.PointerAnalysisPackage#getEInstance() + * @model abstract="true" + * @generated + */ +public interface EInstance extends EObject { +} // EInstance \ No newline at end of file diff --git a/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/pointerAnalysis/EInstanceField.java b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/pointerAnalysis/EInstanceField.java new file mode 100644 index 000000000..19358e6cb --- /dev/null +++ b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/pointerAnalysis/EInstanceField.java @@ -0,0 +1,53 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java.pointerAnalysis; + + +/** + * + * A representation of the model object 'EInstance Field'. + * + * + *

                              + * The following features are supported: + *

                                + *
                              • {@link com.ibm.wala.ecore.java.pointerAnalysis.EInstanceField#getFieldName Field Name}
                              • + *
                              + *

                              + * + * @see com.ibm.wala.ecore.java.pointerAnalysis.PointerAnalysisPackage#getEInstanceField() + * @model + * @generated + */ +public interface EInstanceField extends EPointer { + /** + * Returns the value of the 'Field Name' attribute. + * + *

                              + * If the meaning of the 'Field Name' attribute isn't clear, + * there really should be more of a description here... + *

                              + * + * @return the value of the 'Field Name' attribute. + * @see #setFieldName(String) + * @see com.ibm.wala.ecore.java.pointerAnalysis.PointerAnalysisPackage#getEInstanceField_FieldName() + * @model + * @generated + */ + String getFieldName(); + + /** + * Sets the value of the '{@link com.ibm.wala.ecore.java.pointerAnalysis.EInstanceField#getFieldName Field Name}' attribute. + * + * + * @param value the new value of the 'Field Name' attribute. + * @see #getFieldName() + * @generated + */ + void setFieldName(String value); + +} // EInstanceField \ No newline at end of file diff --git a/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/pointerAnalysis/EJavaClassInstance.java b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/pointerAnalysis/EJavaClassInstance.java new file mode 100644 index 000000000..2d0885148 --- /dev/null +++ b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/pointerAnalysis/EJavaClassInstance.java @@ -0,0 +1,54 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java.pointerAnalysis; + +import com.ibm.wala.ecore.java.EJavaClass; + +/** + * + * A representation of the model object 'EJava Class Instance'. + * + * + *

                              + * The following features are supported: + *

                                + *
                              • {@link com.ibm.wala.ecore.java.pointerAnalysis.EJavaClassInstance#getJavaClass Java Class}
                              • + *
                              + *

                              + * + * @see com.ibm.wala.ecore.java.pointerAnalysis.PointerAnalysisPackage#getEJavaClassInstance() + * @model + * @generated + */ +public interface EJavaClassInstance extends EInstance { + /** + * Returns the value of the 'Java Class' reference. + * + *

                              + * If the meaning of the 'Java Class' reference isn't clear, + * there really should be more of a description here... + *

                              + * + * @return the value of the 'Java Class' reference. + * @see #setJavaClass(EJavaClass) + * @see com.ibm.wala.ecore.java.pointerAnalysis.PointerAnalysisPackage#getEJavaClassInstance_JavaClass() + * @model required="true" + * @generated + */ + EJavaClass getJavaClass(); + + /** + * Sets the value of the '{@link com.ibm.wala.ecore.java.pointerAnalysis.EJavaClassInstance#getJavaClass Java Class}' reference. + * + * + * @param value the new value of the 'Java Class' reference. + * @see #getJavaClass() + * @generated + */ + void setJavaClass(EJavaClass value); + +} // EJavaClassInstance \ No newline at end of file diff --git a/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/pointerAnalysis/ELocalPointer.java b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/pointerAnalysis/ELocalPointer.java new file mode 100644 index 000000000..46e7065d6 --- /dev/null +++ b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/pointerAnalysis/ELocalPointer.java @@ -0,0 +1,81 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java.pointerAnalysis; + +import com.ibm.wala.ecore.java.EJavaMethod; + +/** + * + * A representation of the model object 'ELocal Pointer'. + * + * + *

                              + * The following features are supported: + *

                                + *
                              • {@link com.ibm.wala.ecore.java.pointerAnalysis.ELocalPointer#getValueNumber Value Number}
                              • + *
                              • {@link com.ibm.wala.ecore.java.pointerAnalysis.ELocalPointer#getJavaMethod Java Method}
                              • + *
                              + *

                              + * + * @see com.ibm.wala.ecore.java.pointerAnalysis.PointerAnalysisPackage#getELocalPointer() + * @model + * @generated + */ +public interface ELocalPointer extends EPointer { + /** + * Returns the value of the 'Value Number' attribute. + * + *

                              + * If the meaning of the 'Value Number' attribute isn't clear, + * there really should be more of a description here... + *

                              + * + * @return the value of the 'Value Number' attribute. + * @see #setValueNumber(int) + * @see com.ibm.wala.ecore.java.pointerAnalysis.PointerAnalysisPackage#getELocalPointer_ValueNumber() + * @model required="true" + * @generated + */ + int getValueNumber(); + + /** + * Sets the value of the '{@link com.ibm.wala.ecore.java.pointerAnalysis.ELocalPointer#getValueNumber Value Number}' attribute. + * + * + * @param value the new value of the 'Value Number' attribute. + * @see #getValueNumber() + * @generated + */ + void setValueNumber(int value); + + /** + * Returns the value of the 'Java Method' reference. + * + *

                              + * If the meaning of the 'Java Method' reference isn't clear, + * there really should be more of a description here... + *

                              + * + * @return the value of the 'Java Method' reference. + * @see #setJavaMethod(EJavaMethod) + * @see com.ibm.wala.ecore.java.pointerAnalysis.PointerAnalysisPackage#getELocalPointer_JavaMethod() + * @model required="true" + * @generated + */ + EJavaMethod getJavaMethod(); + + /** + * Sets the value of the '{@link com.ibm.wala.ecore.java.pointerAnalysis.ELocalPointer#getJavaMethod Java Method}' reference. + * + * + * @param value the new value of the 'Java Method' reference. + * @see #getJavaMethod() + * @generated + */ + void setJavaMethod(EJavaMethod value); + +} // ELocalPointer \ No newline at end of file diff --git a/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/pointerAnalysis/EPointer.java b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/pointerAnalysis/EPointer.java new file mode 100644 index 000000000..6d2f642b3 --- /dev/null +++ b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/pointerAnalysis/EPointer.java @@ -0,0 +1,22 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java.pointerAnalysis; + +import org.eclipse.emf.ecore.EObject; + +/** + * + * A representation of the model object 'EPointer'. + * + * + * + * @see com.ibm.wala.ecore.java.pointerAnalysis.PointerAnalysisPackage#getEPointer() + * @model abstract="true" + * @generated + */ +public interface EPointer extends EObject { +} // EPointer \ No newline at end of file diff --git a/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/pointerAnalysis/EReturnValuePointer.java b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/pointerAnalysis/EReturnValuePointer.java new file mode 100644 index 000000000..9d85d4e08 --- /dev/null +++ b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/pointerAnalysis/EReturnValuePointer.java @@ -0,0 +1,81 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java.pointerAnalysis; + +import com.ibm.wala.ecore.java.EJavaMethod; + +/** + * + * A representation of the model object 'EReturn Value Pointer'. + * + * + *

                              + * The following features are supported: + *

                                + *
                              • {@link com.ibm.wala.ecore.java.pointerAnalysis.EReturnValuePointer#isIsExceptionalReturnValue Is Exceptional Return Value}
                              • + *
                              • {@link com.ibm.wala.ecore.java.pointerAnalysis.EReturnValuePointer#getJavaMethod Java Method}
                              • + *
                              + *

                              + * + * @see com.ibm.wala.ecore.java.pointerAnalysis.PointerAnalysisPackage#getEReturnValuePointer() + * @model + * @generated + */ +public interface EReturnValuePointer extends EPointer { + /** + * Returns the value of the 'Is Exceptional Return Value' attribute. + * + *

                              + * If the meaning of the 'Is Exceptional Return Value' attribute isn't clear, + * there really should be more of a description here... + *

                              + * + * @return the value of the 'Is Exceptional Return Value' attribute. + * @see #setIsExceptionalReturnValue(boolean) + * @see com.ibm.wala.ecore.java.pointerAnalysis.PointerAnalysisPackage#getEReturnValuePointer_IsExceptionalReturnValue() + * @model + * @generated + */ + boolean isIsExceptionalReturnValue(); + + /** + * Sets the value of the '{@link com.ibm.wala.ecore.java.pointerAnalysis.EReturnValuePointer#isIsExceptionalReturnValue Is Exceptional Return Value}' attribute. + * + * + * @param value the new value of the 'Is Exceptional Return Value' attribute. + * @see #isIsExceptionalReturnValue() + * @generated + */ + void setIsExceptionalReturnValue(boolean value); + + /** + * Returns the value of the 'Java Method' reference. + * + *

                              + * If the meaning of the 'Java Method' reference isn't clear, + * there really should be more of a description here... + *

                              + * + * @return the value of the 'Java Method' reference. + * @see #setJavaMethod(EJavaMethod) + * @see com.ibm.wala.ecore.java.pointerAnalysis.PointerAnalysisPackage#getEReturnValuePointer_JavaMethod() + * @model required="true" + * @generated + */ + EJavaMethod getJavaMethod(); + + /** + * Sets the value of the '{@link com.ibm.wala.ecore.java.pointerAnalysis.EReturnValuePointer#getJavaMethod Java Method}' reference. + * + * + * @param value the new value of the 'Java Method' reference. + * @see #getJavaMethod() + * @generated + */ + void setJavaMethod(EJavaMethod value); + +} // EReturnValuePointer \ No newline at end of file diff --git a/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/pointerAnalysis/EStaticField.java b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/pointerAnalysis/EStaticField.java new file mode 100644 index 000000000..8b37b9200 --- /dev/null +++ b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/pointerAnalysis/EStaticField.java @@ -0,0 +1,53 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java.pointerAnalysis; + + +/** + * + * A representation of the model object 'EStatic Field'. + * + * + *

                              + * The following features are supported: + *

                                + *
                              • {@link com.ibm.wala.ecore.java.pointerAnalysis.EStaticField#getFieldName Field Name}
                              • + *
                              + *

                              + * + * @see com.ibm.wala.ecore.java.pointerAnalysis.PointerAnalysisPackage#getEStaticField() + * @model + * @generated + */ +public interface EStaticField extends EPointer { + /** + * Returns the value of the 'Field Name' attribute. + * + *

                              + * If the meaning of the 'Field Name' attribute isn't clear, + * there really should be more of a description here... + *

                              + * + * @return the value of the 'Field Name' attribute. + * @see #setFieldName(String) + * @see com.ibm.wala.ecore.java.pointerAnalysis.PointerAnalysisPackage#getEStaticField_FieldName() + * @model + * @generated + */ + String getFieldName(); + + /** + * Sets the value of the '{@link com.ibm.wala.ecore.java.pointerAnalysis.EStaticField#getFieldName Field Name}' attribute. + * + * + * @param value the new value of the 'Field Name' attribute. + * @see #getFieldName() + * @generated + */ + void setFieldName(String value); + +} // EStaticField \ No newline at end of file diff --git a/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/pointerAnalysis/PointerAnalysisFactory.java b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/pointerAnalysis/PointerAnalysisFactory.java new file mode 100644 index 000000000..a990e6dc2 --- /dev/null +++ b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/pointerAnalysis/PointerAnalysisFactory.java @@ -0,0 +1,100 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java.pointerAnalysis; + +import org.eclipse.emf.ecore.EFactory; + +/** + * + * The Factory for the model. + * It provides a create method for each non-abstract class of the model. + * + * @see com.ibm.wala.ecore.java.pointerAnalysis.PointerAnalysisPackage + * @generated + */ +public interface PointerAnalysisFactory extends EFactory { + /** + * The singleton instance of the factory. + * + * + * @generated + */ + PointerAnalysisFactory eINSTANCE = com.ibm.wala.ecore.java.pointerAnalysis.impl.PointerAnalysisFactoryImpl.init(); + + /** + * Returns a new object of class 'EInstance Field'. + * + * + * @return a new object of class 'EInstance Field'. + * @generated + */ + EInstanceField createEInstanceField(); + + /** + * Returns a new object of class 'EArray Contents'. + * + * + * @return a new object of class 'EArray Contents'. + * @generated + */ + EArrayContents createEArrayContents(); + + /** + * Returns a new object of class 'EStatic Field'. + * + * + * @return a new object of class 'EStatic Field'. + * @generated + */ + EStaticField createEStaticField(); + + /** + * Returns a new object of class 'ELocal Pointer'. + * + * + * @return a new object of class 'ELocal Pointer'. + * @generated + */ + ELocalPointer createELocalPointer(); + + /** + * Returns a new object of class 'EReturn Value Pointer'. + * + * + * @return a new object of class 'EReturn Value Pointer'. + * @generated + */ + EReturnValuePointer createEReturnValuePointer(); + + /** + * Returns a new object of class 'EJava Class Instance'. + * + * + * @return a new object of class 'EJava Class Instance'. + * @generated + */ + EJavaClassInstance createEJavaClassInstance(); + + /** + * Returns a new object of class 'EHeap Graph'. + * + * + * @return a new object of class 'EHeap Graph'. + * @generated + */ + EHeapGraph createEHeapGraph(); + + /** + * Returns the package supported by this factory. + * + * + * @return the package supported by this factory. + * @generated + */ + PointerAnalysisPackage getPointerAnalysisPackage(); + +} //PointerAnalysisFactory diff --git a/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/pointerAnalysis/PointerAnalysisPackage.java b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/pointerAnalysis/PointerAnalysisPackage.java new file mode 100644 index 000000000..9adffee10 --- /dev/null +++ b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/pointerAnalysis/PointerAnalysisPackage.java @@ -0,0 +1,682 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java.pointerAnalysis; + +import com.ibm.wala.ecore.graph.GraphPackage; + +import org.eclipse.emf.ecore.EAttribute; +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EPackage; +import org.eclipse.emf.ecore.EReference; + +/** + * + * The Package for the model. + * It contains accessors for the meta objects to represent + *
                                + *
                              • each class,
                              • + *
                              • each feature of each class,
                              • + *
                              • each enum,
                              • + *
                              • and each data type
                              • + *
                              + * + * @see com.ibm.wala.ecore.java.pointerAnalysis.PointerAnalysisFactory + * @model kind="package" + * @generated + */ +public interface PointerAnalysisPackage extends EPackage { + /** + * The package name. + * + * + * @generated + */ + String eNAME = "pointerAnalysis"; + + /** + * The package namespace URI. + * + * + * @generated + */ + String eNS_URI = "http:///com/ibm/wala/wala.ecore.java.pointerAnalysis"; + + /** + * The package namespace name. + * + * + * @generated + */ + String eNS_PREFIX = "com.ibm.wala.java.pointerAnalysis"; + + /** + * The singleton instance of the package. + * + * + * @generated + */ + PointerAnalysisPackage eINSTANCE = com.ibm.wala.ecore.java.pointerAnalysis.impl.PointerAnalysisPackageImpl.init(); + + /** + * The meta object id for the '{@link com.ibm.wala.ecore.java.pointerAnalysis.impl.EPointerImpl EPointer}' class. + * + * + * @see com.ibm.wala.ecore.java.pointerAnalysis.impl.EPointerImpl + * @see com.ibm.wala.ecore.java.pointerAnalysis.impl.PointerAnalysisPackageImpl#getEPointer() + * @generated + */ + int EPOINTER = 0; + + /** + * The number of structural features of the 'EPointer' class. + * + * + * @generated + * @ordered + */ + int EPOINTER_FEATURE_COUNT = 0; + + /** + * The meta object id for the '{@link com.ibm.wala.ecore.java.pointerAnalysis.impl.EInstanceFieldImpl EInstance Field}' class. + * + * + * @see com.ibm.wala.ecore.java.pointerAnalysis.impl.EInstanceFieldImpl + * @see com.ibm.wala.ecore.java.pointerAnalysis.impl.PointerAnalysisPackageImpl#getEInstanceField() + * @generated + */ + int EINSTANCE_FIELD = 1; + + /** + * The feature id for the 'Field Name' attribute. + * + * + * @generated + * @ordered + */ + int EINSTANCE_FIELD__FIELD_NAME = EPOINTER_FEATURE_COUNT + 0; + + /** + * The number of structural features of the 'EInstance Field' class. + * + * + * @generated + * @ordered + */ + int EINSTANCE_FIELD_FEATURE_COUNT = EPOINTER_FEATURE_COUNT + 1; + + /** + * The meta object id for the '{@link com.ibm.wala.ecore.java.pointerAnalysis.impl.EArrayContentsImpl EArray Contents}' class. + * + * + * @see com.ibm.wala.ecore.java.pointerAnalysis.impl.EArrayContentsImpl + * @see com.ibm.wala.ecore.java.pointerAnalysis.impl.PointerAnalysisPackageImpl#getEArrayContents() + * @generated + */ + int EARRAY_CONTENTS = 2; + + /** + * The feature id for the 'Java Class' reference. + * + * + * @generated + * @ordered + */ + int EARRAY_CONTENTS__JAVA_CLASS = EPOINTER_FEATURE_COUNT + 0; + + /** + * The number of structural features of the 'EArray Contents' class. + * + * + * @generated + * @ordered + */ + int EARRAY_CONTENTS_FEATURE_COUNT = EPOINTER_FEATURE_COUNT + 1; + + /** + * The meta object id for the '{@link com.ibm.wala.ecore.java.pointerAnalysis.impl.EStaticFieldImpl EStatic Field}' class. + * + * + * @see com.ibm.wala.ecore.java.pointerAnalysis.impl.EStaticFieldImpl + * @see com.ibm.wala.ecore.java.pointerAnalysis.impl.PointerAnalysisPackageImpl#getEStaticField() + * @generated + */ + int ESTATIC_FIELD = 3; + + /** + * The feature id for the 'Field Name' attribute. + * + * + * @generated + * @ordered + */ + int ESTATIC_FIELD__FIELD_NAME = EPOINTER_FEATURE_COUNT + 0; + + /** + * The number of structural features of the 'EStatic Field' class. + * + * + * @generated + * @ordered + */ + int ESTATIC_FIELD_FEATURE_COUNT = EPOINTER_FEATURE_COUNT + 1; + + /** + * The meta object id for the '{@link com.ibm.wala.ecore.java.pointerAnalysis.impl.ELocalPointerImpl ELocal Pointer}' class. + * + * + * @see com.ibm.wala.ecore.java.pointerAnalysis.impl.ELocalPointerImpl + * @see com.ibm.wala.ecore.java.pointerAnalysis.impl.PointerAnalysisPackageImpl#getELocalPointer() + * @generated + */ + int ELOCAL_POINTER = 4; + + /** + * The feature id for the 'Value Number' attribute. + * + * + * @generated + * @ordered + */ + int ELOCAL_POINTER__VALUE_NUMBER = EPOINTER_FEATURE_COUNT + 0; + + /** + * The feature id for the 'Java Method' reference. + * + * + * @generated + * @ordered + */ + int ELOCAL_POINTER__JAVA_METHOD = EPOINTER_FEATURE_COUNT + 1; + + /** + * The number of structural features of the 'ELocal Pointer' class. + * + * + * @generated + * @ordered + */ + int ELOCAL_POINTER_FEATURE_COUNT = EPOINTER_FEATURE_COUNT + 2; + + /** + * The meta object id for the '{@link com.ibm.wala.ecore.java.pointerAnalysis.impl.EReturnValuePointerImpl EReturn Value Pointer}' class. + * + * + * @see com.ibm.wala.ecore.java.pointerAnalysis.impl.EReturnValuePointerImpl + * @see com.ibm.wala.ecore.java.pointerAnalysis.impl.PointerAnalysisPackageImpl#getEReturnValuePointer() + * @generated + */ + int ERETURN_VALUE_POINTER = 5; + + /** + * The feature id for the 'Is Exceptional Return Value' attribute. + * + * + * @generated + * @ordered + */ + int ERETURN_VALUE_POINTER__IS_EXCEPTIONAL_RETURN_VALUE = EPOINTER_FEATURE_COUNT + 0; + + /** + * The feature id for the 'Java Method' reference. + * + * + * @generated + * @ordered + */ + int ERETURN_VALUE_POINTER__JAVA_METHOD = EPOINTER_FEATURE_COUNT + 1; + + /** + * The number of structural features of the 'EReturn Value Pointer' class. + * + * + * @generated + * @ordered + */ + int ERETURN_VALUE_POINTER_FEATURE_COUNT = EPOINTER_FEATURE_COUNT + 2; + + /** + * The meta object id for the '{@link com.ibm.wala.ecore.java.pointerAnalysis.impl.EInstanceImpl EInstance}' class. + * + * + * @see com.ibm.wala.ecore.java.pointerAnalysis.impl.EInstanceImpl + * @see com.ibm.wala.ecore.java.pointerAnalysis.impl.PointerAnalysisPackageImpl#getEInstance() + * @generated + */ + int EINSTANCE = 6; + + /** + * The number of structural features of the 'EInstance' class. + * + * + * @generated + * @ordered + */ + int EINSTANCE_FEATURE_COUNT = 0; + + /** + * The meta object id for the '{@link com.ibm.wala.ecore.java.pointerAnalysis.impl.EJavaClassInstanceImpl EJava Class Instance}' class. + * + * + * @see com.ibm.wala.ecore.java.pointerAnalysis.impl.EJavaClassInstanceImpl + * @see com.ibm.wala.ecore.java.pointerAnalysis.impl.PointerAnalysisPackageImpl#getEJavaClassInstance() + * @generated + */ + int EJAVA_CLASS_INSTANCE = 7; + + /** + * The feature id for the 'Java Class' reference. + * + * + * @generated + * @ordered + */ + int EJAVA_CLASS_INSTANCE__JAVA_CLASS = EINSTANCE_FEATURE_COUNT + 0; + + /** + * The number of structural features of the 'EJava Class Instance' class. + * + * + * @generated + * @ordered + */ + int EJAVA_CLASS_INSTANCE_FEATURE_COUNT = EINSTANCE_FEATURE_COUNT + 1; + + /** + * The meta object id for the '{@link com.ibm.wala.ecore.java.pointerAnalysis.impl.EHeapGraphImpl EHeap Graph}' class. + * + * + * @see com.ibm.wala.ecore.java.pointerAnalysis.impl.EHeapGraphImpl + * @see com.ibm.wala.ecore.java.pointerAnalysis.impl.PointerAnalysisPackageImpl#getEHeapGraph() + * @generated + */ + int EHEAP_GRAPH = 8; + + /** + * The feature id for the 'Nodes' reference. + * + * + * @generated + * @ordered + */ + int EHEAP_GRAPH__NODES = GraphPackage.EGRAPH__NODES; + + /** + * The feature id for the 'Edges' containment reference. + * + * + * @generated + * @ordered + */ + int EHEAP_GRAPH__EDGES = GraphPackage.EGRAPH__EDGES; + + /** + * The number of structural features of the 'EHeap Graph' class. + * + * + * @generated + * @ordered + */ + int EHEAP_GRAPH_FEATURE_COUNT = GraphPackage.EGRAPH_FEATURE_COUNT + 0; + + + /** + * Returns the meta object for class '{@link com.ibm.wala.ecore.java.pointerAnalysis.EPointer EPointer}'. + * + * + * @return the meta object for class 'EPointer'. + * @see com.ibm.wala.ecore.java.pointerAnalysis.EPointer + * @generated + */ + EClass getEPointer(); + + /** + * Returns the meta object for class '{@link com.ibm.wala.ecore.java.pointerAnalysis.EInstanceField EInstance Field}'. + * + * + * @return the meta object for class 'EInstance Field'. + * @see com.ibm.wala.ecore.java.pointerAnalysis.EInstanceField + * @generated + */ + EClass getEInstanceField(); + + /** + * Returns the meta object for the attribute '{@link com.ibm.wala.ecore.java.pointerAnalysis.EInstanceField#getFieldName Field Name}'. + * + * + * @return the meta object for the attribute 'Field Name'. + * @see com.ibm.wala.ecore.java.pointerAnalysis.EInstanceField#getFieldName() + * @see #getEInstanceField() + * @generated + */ + EAttribute getEInstanceField_FieldName(); + + /** + * Returns the meta object for class '{@link com.ibm.wala.ecore.java.pointerAnalysis.EArrayContents EArray Contents}'. + * + * + * @return the meta object for class 'EArray Contents'. + * @see com.ibm.wala.ecore.java.pointerAnalysis.EArrayContents + * @generated + */ + EClass getEArrayContents(); + + /** + * Returns the meta object for the reference '{@link com.ibm.wala.ecore.java.pointerAnalysis.EArrayContents#getJavaClass Java Class}'. + * + * + * @return the meta object for the reference 'Java Class'. + * @see com.ibm.wala.ecore.java.pointerAnalysis.EArrayContents#getJavaClass() + * @see #getEArrayContents() + * @generated + */ + EReference getEArrayContents_JavaClass(); + + /** + * Returns the meta object for class '{@link com.ibm.wala.ecore.java.pointerAnalysis.EStaticField EStatic Field}'. + * + * + * @return the meta object for class 'EStatic Field'. + * @see com.ibm.wala.ecore.java.pointerAnalysis.EStaticField + * @generated + */ + EClass getEStaticField(); + + /** + * Returns the meta object for the attribute '{@link com.ibm.wala.ecore.java.pointerAnalysis.EStaticField#getFieldName Field Name}'. + * + * + * @return the meta object for the attribute 'Field Name'. + * @see com.ibm.wala.ecore.java.pointerAnalysis.EStaticField#getFieldName() + * @see #getEStaticField() + * @generated + */ + EAttribute getEStaticField_FieldName(); + + /** + * Returns the meta object for class '{@link com.ibm.wala.ecore.java.pointerAnalysis.ELocalPointer ELocal Pointer}'. + * + * + * @return the meta object for class 'ELocal Pointer'. + * @see com.ibm.wala.ecore.java.pointerAnalysis.ELocalPointer + * @generated + */ + EClass getELocalPointer(); + + /** + * Returns the meta object for the attribute '{@link com.ibm.wala.ecore.java.pointerAnalysis.ELocalPointer#getValueNumber Value Number}'. + * + * + * @return the meta object for the attribute 'Value Number'. + * @see com.ibm.wala.ecore.java.pointerAnalysis.ELocalPointer#getValueNumber() + * @see #getELocalPointer() + * @generated + */ + EAttribute getELocalPointer_ValueNumber(); + + /** + * Returns the meta object for the reference '{@link com.ibm.wala.ecore.java.pointerAnalysis.ELocalPointer#getJavaMethod Java Method}'. + * + * + * @return the meta object for the reference 'Java Method'. + * @see com.ibm.wala.ecore.java.pointerAnalysis.ELocalPointer#getJavaMethod() + * @see #getELocalPointer() + * @generated + */ + EReference getELocalPointer_JavaMethod(); + + /** + * Returns the meta object for class '{@link com.ibm.wala.ecore.java.pointerAnalysis.EReturnValuePointer EReturn Value Pointer}'. + * + * + * @return the meta object for class 'EReturn Value Pointer'. + * @see com.ibm.wala.ecore.java.pointerAnalysis.EReturnValuePointer + * @generated + */ + EClass getEReturnValuePointer(); + + /** + * Returns the meta object for the attribute '{@link com.ibm.wala.ecore.java.pointerAnalysis.EReturnValuePointer#isIsExceptionalReturnValue Is Exceptional Return Value}'. + * + * + * @return the meta object for the attribute 'Is Exceptional Return Value'. + * @see com.ibm.wala.ecore.java.pointerAnalysis.EReturnValuePointer#isIsExceptionalReturnValue() + * @see #getEReturnValuePointer() + * @generated + */ + EAttribute getEReturnValuePointer_IsExceptionalReturnValue(); + + /** + * Returns the meta object for the reference '{@link com.ibm.wala.ecore.java.pointerAnalysis.EReturnValuePointer#getJavaMethod Java Method}'. + * + * + * @return the meta object for the reference 'Java Method'. + * @see com.ibm.wala.ecore.java.pointerAnalysis.EReturnValuePointer#getJavaMethod() + * @see #getEReturnValuePointer() + * @generated + */ + EReference getEReturnValuePointer_JavaMethod(); + + /** + * Returns the meta object for class '{@link com.ibm.wala.ecore.java.pointerAnalysis.EInstance EInstance}'. + * + * + * @return the meta object for class 'EInstance'. + * @see com.ibm.wala.ecore.java.pointerAnalysis.EInstance + * @generated + */ + EClass getEInstance(); + + /** + * Returns the meta object for class '{@link com.ibm.wala.ecore.java.pointerAnalysis.EJavaClassInstance EJava Class Instance}'. + * + * + * @return the meta object for class 'EJava Class Instance'. + * @see com.ibm.wala.ecore.java.pointerAnalysis.EJavaClassInstance + * @generated + */ + EClass getEJavaClassInstance(); + + /** + * Returns the meta object for the reference '{@link com.ibm.wala.ecore.java.pointerAnalysis.EJavaClassInstance#getJavaClass Java Class}'. + * + * + * @return the meta object for the reference 'Java Class'. + * @see com.ibm.wala.ecore.java.pointerAnalysis.EJavaClassInstance#getJavaClass() + * @see #getEJavaClassInstance() + * @generated + */ + EReference getEJavaClassInstance_JavaClass(); + + /** + * Returns the meta object for class '{@link com.ibm.wala.ecore.java.pointerAnalysis.EHeapGraph EHeap Graph}'. + * + * + * @return the meta object for class 'EHeap Graph'. + * @see com.ibm.wala.ecore.java.pointerAnalysis.EHeapGraph + * @generated + */ + EClass getEHeapGraph(); + + /** + * Returns the factory that creates the instances of the model. + * + * + * @return the factory that creates the instances of the model. + * @generated + */ + PointerAnalysisFactory getPointerAnalysisFactory(); + + /** + * + * Defines literals for the meta objects that represent + *
                                + *
                              • each class,
                              • + *
                              • each feature of each class,
                              • + *
                              • each enum,
                              • + *
                              • and each data type
                              • + *
                              + * + * @generated + */ + interface Literals { + /** + * The meta object literal for the '{@link com.ibm.wala.ecore.java.pointerAnalysis.impl.EPointerImpl EPointer}' class. + * + * + * @see com.ibm.wala.ecore.java.pointerAnalysis.impl.EPointerImpl + * @see com.ibm.wala.ecore.java.pointerAnalysis.impl.PointerAnalysisPackageImpl#getEPointer() + * @generated + */ + EClass EPOINTER = eINSTANCE.getEPointer(); + + /** + * The meta object literal for the '{@link com.ibm.wala.ecore.java.pointerAnalysis.impl.EInstanceFieldImpl EInstance Field}' class. + * + * + * @see com.ibm.wala.ecore.java.pointerAnalysis.impl.EInstanceFieldImpl + * @see com.ibm.wala.ecore.java.pointerAnalysis.impl.PointerAnalysisPackageImpl#getEInstanceField() + * @generated + */ + EClass EINSTANCE_FIELD = eINSTANCE.getEInstanceField(); + + /** + * The meta object literal for the 'Field Name' attribute feature. + * + * + * @generated + */ + EAttribute EINSTANCE_FIELD__FIELD_NAME = eINSTANCE.getEInstanceField_FieldName(); + + /** + * The meta object literal for the '{@link com.ibm.wala.ecore.java.pointerAnalysis.impl.EArrayContentsImpl EArray Contents}' class. + * + * + * @see com.ibm.wala.ecore.java.pointerAnalysis.impl.EArrayContentsImpl + * @see com.ibm.wala.ecore.java.pointerAnalysis.impl.PointerAnalysisPackageImpl#getEArrayContents() + * @generated + */ + EClass EARRAY_CONTENTS = eINSTANCE.getEArrayContents(); + + /** + * The meta object literal for the 'Java Class' reference feature. + * + * + * @generated + */ + EReference EARRAY_CONTENTS__JAVA_CLASS = eINSTANCE.getEArrayContents_JavaClass(); + + /** + * The meta object literal for the '{@link com.ibm.wala.ecore.java.pointerAnalysis.impl.EStaticFieldImpl EStatic Field}' class. + * + * + * @see com.ibm.wala.ecore.java.pointerAnalysis.impl.EStaticFieldImpl + * @see com.ibm.wala.ecore.java.pointerAnalysis.impl.PointerAnalysisPackageImpl#getEStaticField() + * @generated + */ + EClass ESTATIC_FIELD = eINSTANCE.getEStaticField(); + + /** + * The meta object literal for the 'Field Name' attribute feature. + * + * + * @generated + */ + EAttribute ESTATIC_FIELD__FIELD_NAME = eINSTANCE.getEStaticField_FieldName(); + + /** + * The meta object literal for the '{@link com.ibm.wala.ecore.java.pointerAnalysis.impl.ELocalPointerImpl ELocal Pointer}' class. + * + * + * @see com.ibm.wala.ecore.java.pointerAnalysis.impl.ELocalPointerImpl + * @see com.ibm.wala.ecore.java.pointerAnalysis.impl.PointerAnalysisPackageImpl#getELocalPointer() + * @generated + */ + EClass ELOCAL_POINTER = eINSTANCE.getELocalPointer(); + + /** + * The meta object literal for the 'Value Number' attribute feature. + * + * + * @generated + */ + EAttribute ELOCAL_POINTER__VALUE_NUMBER = eINSTANCE.getELocalPointer_ValueNumber(); + + /** + * The meta object literal for the 'Java Method' reference feature. + * + * + * @generated + */ + EReference ELOCAL_POINTER__JAVA_METHOD = eINSTANCE.getELocalPointer_JavaMethod(); + + /** + * The meta object literal for the '{@link com.ibm.wala.ecore.java.pointerAnalysis.impl.EReturnValuePointerImpl EReturn Value Pointer}' class. + * + * + * @see com.ibm.wala.ecore.java.pointerAnalysis.impl.EReturnValuePointerImpl + * @see com.ibm.wala.ecore.java.pointerAnalysis.impl.PointerAnalysisPackageImpl#getEReturnValuePointer() + * @generated + */ + EClass ERETURN_VALUE_POINTER = eINSTANCE.getEReturnValuePointer(); + + /** + * The meta object literal for the 'Is Exceptional Return Value' attribute feature. + * + * + * @generated + */ + EAttribute ERETURN_VALUE_POINTER__IS_EXCEPTIONAL_RETURN_VALUE = eINSTANCE.getEReturnValuePointer_IsExceptionalReturnValue(); + + /** + * The meta object literal for the 'Java Method' reference feature. + * + * + * @generated + */ + EReference ERETURN_VALUE_POINTER__JAVA_METHOD = eINSTANCE.getEReturnValuePointer_JavaMethod(); + + /** + * The meta object literal for the '{@link com.ibm.wala.ecore.java.pointerAnalysis.impl.EInstanceImpl EInstance}' class. + * + * + * @see com.ibm.wala.ecore.java.pointerAnalysis.impl.EInstanceImpl + * @see com.ibm.wala.ecore.java.pointerAnalysis.impl.PointerAnalysisPackageImpl#getEInstance() + * @generated + */ + EClass EINSTANCE = eINSTANCE.getEInstance(); + + /** + * The meta object literal for the '{@link com.ibm.wala.ecore.java.pointerAnalysis.impl.EJavaClassInstanceImpl EJava Class Instance}' class. + * + * + * @see com.ibm.wala.ecore.java.pointerAnalysis.impl.EJavaClassInstanceImpl + * @see com.ibm.wala.ecore.java.pointerAnalysis.impl.PointerAnalysisPackageImpl#getEJavaClassInstance() + * @generated + */ + EClass EJAVA_CLASS_INSTANCE = eINSTANCE.getEJavaClassInstance(); + + /** + * The meta object literal for the 'Java Class' reference feature. + * + * + * @generated + */ + EReference EJAVA_CLASS_INSTANCE__JAVA_CLASS = eINSTANCE.getEJavaClassInstance_JavaClass(); + + /** + * The meta object literal for the '{@link com.ibm.wala.ecore.java.pointerAnalysis.impl.EHeapGraphImpl EHeap Graph}' class. + * + * + * @see com.ibm.wala.ecore.java.pointerAnalysis.impl.EHeapGraphImpl + * @see com.ibm.wala.ecore.java.pointerAnalysis.impl.PointerAnalysisPackageImpl#getEHeapGraph() + * @generated + */ + EClass EHEAP_GRAPH = eINSTANCE.getEHeapGraph(); + + } + +} //PointerAnalysisPackage diff --git a/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/pointerAnalysis/impl/EArrayContentsImpl.java b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/pointerAnalysis/impl/EArrayContentsImpl.java new file mode 100644 index 000000000..688441fcd --- /dev/null +++ b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/pointerAnalysis/impl/EArrayContentsImpl.java @@ -0,0 +1,156 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java.pointerAnalysis.impl; + +import com.ibm.wala.ecore.java.EJavaClass; + +import com.ibm.wala.ecore.java.pointerAnalysis.EArrayContents; +import com.ibm.wala.ecore.java.pointerAnalysis.PointerAnalysisPackage; + +import org.eclipse.emf.common.notify.Notification; + +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.InternalEObject; + +import org.eclipse.emf.ecore.impl.ENotificationImpl; + +/** + * + * An implementation of the model object 'EArray Contents'. + * + *

                              + * The following features are implemented: + *

                                + *
                              • {@link com.ibm.wala.ecore.java.pointerAnalysis.impl.EArrayContentsImpl#getJavaClass Java Class}
                              • + *
                              + *

                              + * + * @generated + */ +public class EArrayContentsImpl extends EPointerImpl implements EArrayContents { + /** + * The cached value of the '{@link #getJavaClass() Java Class}' reference. + * + * + * @see #getJavaClass() + * @generated + * @ordered + */ + protected EJavaClass javaClass = null; + + /** + * + * + * @generated + */ + protected EArrayContentsImpl() { + super(); + } + + /** + * + * + * @generated + */ + protected EClass eStaticClass() { + return PointerAnalysisPackage.Literals.EARRAY_CONTENTS; + } + + /** + * + * + * @generated + */ + public EJavaClass getJavaClass() { + if (javaClass != null && javaClass.eIsProxy()) { + InternalEObject oldJavaClass = (InternalEObject)javaClass; + javaClass = (EJavaClass)eResolveProxy(oldJavaClass); + if (javaClass != oldJavaClass) { + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.RESOLVE, PointerAnalysisPackage.EARRAY_CONTENTS__JAVA_CLASS, oldJavaClass, javaClass)); + } + } + return javaClass; + } + + /** + * + * + * @generated + */ + public EJavaClass basicGetJavaClass() { + return javaClass; + } + + /** + * + * + * @generated + */ + public void setJavaClass(EJavaClass newJavaClass) { + EJavaClass oldJavaClass = javaClass; + javaClass = newJavaClass; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, PointerAnalysisPackage.EARRAY_CONTENTS__JAVA_CLASS, oldJavaClass, javaClass)); + } + + /** + * + * + * @generated + */ + public Object eGet(int featureID, boolean resolve, boolean coreType) { + switch (featureID) { + case PointerAnalysisPackage.EARRAY_CONTENTS__JAVA_CLASS: + if (resolve) return getJavaClass(); + return basicGetJavaClass(); + } + return super.eGet(featureID, resolve, coreType); + } + + /** + * + * + * @generated + */ + public void eSet(int featureID, Object newValue) { + switch (featureID) { + case PointerAnalysisPackage.EARRAY_CONTENTS__JAVA_CLASS: + setJavaClass((EJavaClass)newValue); + return; + } + super.eSet(featureID, newValue); + } + + /** + * + * + * @generated + */ + public void eUnset(int featureID) { + switch (featureID) { + case PointerAnalysisPackage.EARRAY_CONTENTS__JAVA_CLASS: + setJavaClass((EJavaClass)null); + return; + } + super.eUnset(featureID); + } + + /** + * + * + * @generated + */ + public boolean eIsSet(int featureID) { + switch (featureID) { + case PointerAnalysisPackage.EARRAY_CONTENTS__JAVA_CLASS: + return javaClass != null; + } + return super.eIsSet(featureID); + } + +} //EArrayContentsImpl \ No newline at end of file diff --git a/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/pointerAnalysis/impl/EHeapGraphImpl.java b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/pointerAnalysis/impl/EHeapGraphImpl.java new file mode 100644 index 000000000..9cc1b71f4 --- /dev/null +++ b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/pointerAnalysis/impl/EHeapGraphImpl.java @@ -0,0 +1,44 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java.pointerAnalysis.impl; + +import com.ibm.wala.ecore.graph.impl.EGraphImpl; + +import com.ibm.wala.ecore.java.pointerAnalysis.EHeapGraph; +import com.ibm.wala.ecore.java.pointerAnalysis.PointerAnalysisPackage; + +import org.eclipse.emf.ecore.EClass; + +/** + * + * An implementation of the model object 'EHeap Graph'. + * + *

                              + *

                              + * + * @generated + */ +public class EHeapGraphImpl extends EGraphImpl implements EHeapGraph { + /** + * + * + * @generated + */ + protected EHeapGraphImpl() { + super(); + } + + /** + * + * + * @generated + */ + protected EClass eStaticClass() { + return PointerAnalysisPackage.Literals.EHEAP_GRAPH; + } + +} //EHeapGraphImpl \ No newline at end of file diff --git a/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/pointerAnalysis/impl/EInstanceFieldImpl.java b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/pointerAnalysis/impl/EInstanceFieldImpl.java new file mode 100644 index 000000000..a89fbf46c --- /dev/null +++ b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/pointerAnalysis/impl/EInstanceFieldImpl.java @@ -0,0 +1,160 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java.pointerAnalysis.impl; + +import com.ibm.wala.ecore.java.pointerAnalysis.EInstanceField; +import com.ibm.wala.ecore.java.pointerAnalysis.PointerAnalysisPackage; + +import org.eclipse.emf.common.notify.Notification; + +import org.eclipse.emf.ecore.EClass; + +import org.eclipse.emf.ecore.impl.ENotificationImpl; + +/** + * + * An implementation of the model object 'EInstance Field'. + * + *

                              + * The following features are implemented: + *

                                + *
                              • {@link com.ibm.wala.ecore.java.pointerAnalysis.impl.EInstanceFieldImpl#getFieldName Field Name}
                              • + *
                              + *

                              + * + * @generated + */ +public class EInstanceFieldImpl extends EPointerImpl implements EInstanceField { + /** + * The default value of the '{@link #getFieldName() Field Name}' attribute. + * + * + * @see #getFieldName() + * @generated + * @ordered + */ + protected static final String FIELD_NAME_EDEFAULT = null; + + /** + * The cached value of the '{@link #getFieldName() Field Name}' attribute. + * + * + * @see #getFieldName() + * @generated + * @ordered + */ + protected String fieldName = FIELD_NAME_EDEFAULT; + + /** + * + * + * @generated + */ + protected EInstanceFieldImpl() { + super(); + } + + /** + * + * + * @generated + */ + protected EClass eStaticClass() { + return PointerAnalysisPackage.Literals.EINSTANCE_FIELD; + } + + /** + * + * + * @generated + */ + public String getFieldName() { + return fieldName; + } + + /** + * + * + * @generated + */ + public void setFieldName(String newFieldName) { + String oldFieldName = fieldName; + fieldName = newFieldName; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, PointerAnalysisPackage.EINSTANCE_FIELD__FIELD_NAME, oldFieldName, fieldName)); + } + + /** + * + * + * @generated + */ + public Object eGet(int featureID, boolean resolve, boolean coreType) { + switch (featureID) { + case PointerAnalysisPackage.EINSTANCE_FIELD__FIELD_NAME: + return getFieldName(); + } + return super.eGet(featureID, resolve, coreType); + } + + /** + * + * + * @generated + */ + public void eSet(int featureID, Object newValue) { + switch (featureID) { + case PointerAnalysisPackage.EINSTANCE_FIELD__FIELD_NAME: + setFieldName((String)newValue); + return; + } + super.eSet(featureID, newValue); + } + + /** + * + * + * @generated + */ + public void eUnset(int featureID) { + switch (featureID) { + case PointerAnalysisPackage.EINSTANCE_FIELD__FIELD_NAME: + setFieldName(FIELD_NAME_EDEFAULT); + return; + } + super.eUnset(featureID); + } + + /** + * + * + * @generated + */ + public boolean eIsSet(int featureID) { + switch (featureID) { + case PointerAnalysisPackage.EINSTANCE_FIELD__FIELD_NAME: + return FIELD_NAME_EDEFAULT == null ? fieldName != null : !FIELD_NAME_EDEFAULT.equals(fieldName); + } + return super.eIsSet(featureID); + } + + /** + * + * + * @generated + */ + public String toString() { + if (eIsProxy()) return super.toString(); + + StringBuffer result = new StringBuffer(super.toString()); + result.append(" (fieldName: "); + result.append(fieldName); + result.append(')'); + return result.toString(); + } + +} //EInstanceFieldImpl \ No newline at end of file diff --git a/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/pointerAnalysis/impl/EInstanceImpl.java b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/pointerAnalysis/impl/EInstanceImpl.java new file mode 100644 index 000000000..8cbf23e79 --- /dev/null +++ b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/pointerAnalysis/impl/EInstanceImpl.java @@ -0,0 +1,44 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java.pointerAnalysis.impl; + +import com.ibm.wala.ecore.java.pointerAnalysis.EInstance; +import com.ibm.wala.ecore.java.pointerAnalysis.PointerAnalysisPackage; + +import org.eclipse.emf.ecore.EClass; + +import org.eclipse.emf.ecore.impl.EObjectImpl; + +/** + * + * An implementation of the model object 'EInstance'. + * + *

                              + *

                              + * + * @generated + */ +public abstract class EInstanceImpl extends EObjectImpl implements EInstance { + /** + * + * + * @generated + */ + protected EInstanceImpl() { + super(); + } + + /** + * + * + * @generated + */ + protected EClass eStaticClass() { + return PointerAnalysisPackage.Literals.EINSTANCE; + } + +} //EInstanceImpl \ No newline at end of file diff --git a/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/pointerAnalysis/impl/EJavaClassInstanceImpl.java b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/pointerAnalysis/impl/EJavaClassInstanceImpl.java new file mode 100644 index 000000000..a88d6938b --- /dev/null +++ b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/pointerAnalysis/impl/EJavaClassInstanceImpl.java @@ -0,0 +1,156 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java.pointerAnalysis.impl; + +import com.ibm.wala.ecore.java.EJavaClass; + +import com.ibm.wala.ecore.java.pointerAnalysis.EJavaClassInstance; +import com.ibm.wala.ecore.java.pointerAnalysis.PointerAnalysisPackage; + +import org.eclipse.emf.common.notify.Notification; + +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.InternalEObject; + +import org.eclipse.emf.ecore.impl.ENotificationImpl; + +/** + * + * An implementation of the model object 'EJava Class Instance'. + * + *

                              + * The following features are implemented: + *

                                + *
                              • {@link com.ibm.wala.ecore.java.pointerAnalysis.impl.EJavaClassInstanceImpl#getJavaClass Java Class}
                              • + *
                              + *

                              + * + * @generated + */ +public class EJavaClassInstanceImpl extends EInstanceImpl implements EJavaClassInstance { + /** + * The cached value of the '{@link #getJavaClass() Java Class}' reference. + * + * + * @see #getJavaClass() + * @generated + * @ordered + */ + protected EJavaClass javaClass = null; + + /** + * + * + * @generated + */ + protected EJavaClassInstanceImpl() { + super(); + } + + /** + * + * + * @generated + */ + protected EClass eStaticClass() { + return PointerAnalysisPackage.Literals.EJAVA_CLASS_INSTANCE; + } + + /** + * + * + * @generated + */ + public EJavaClass getJavaClass() { + if (javaClass != null && javaClass.eIsProxy()) { + InternalEObject oldJavaClass = (InternalEObject)javaClass; + javaClass = (EJavaClass)eResolveProxy(oldJavaClass); + if (javaClass != oldJavaClass) { + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.RESOLVE, PointerAnalysisPackage.EJAVA_CLASS_INSTANCE__JAVA_CLASS, oldJavaClass, javaClass)); + } + } + return javaClass; + } + + /** + * + * + * @generated + */ + public EJavaClass basicGetJavaClass() { + return javaClass; + } + + /** + * + * + * @generated + */ + public void setJavaClass(EJavaClass newJavaClass) { + EJavaClass oldJavaClass = javaClass; + javaClass = newJavaClass; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, PointerAnalysisPackage.EJAVA_CLASS_INSTANCE__JAVA_CLASS, oldJavaClass, javaClass)); + } + + /** + * + * + * @generated + */ + public Object eGet(int featureID, boolean resolve, boolean coreType) { + switch (featureID) { + case PointerAnalysisPackage.EJAVA_CLASS_INSTANCE__JAVA_CLASS: + if (resolve) return getJavaClass(); + return basicGetJavaClass(); + } + return super.eGet(featureID, resolve, coreType); + } + + /** + * + * + * @generated + */ + public void eSet(int featureID, Object newValue) { + switch (featureID) { + case PointerAnalysisPackage.EJAVA_CLASS_INSTANCE__JAVA_CLASS: + setJavaClass((EJavaClass)newValue); + return; + } + super.eSet(featureID, newValue); + } + + /** + * + * + * @generated + */ + public void eUnset(int featureID) { + switch (featureID) { + case PointerAnalysisPackage.EJAVA_CLASS_INSTANCE__JAVA_CLASS: + setJavaClass((EJavaClass)null); + return; + } + super.eUnset(featureID); + } + + /** + * + * + * @generated + */ + public boolean eIsSet(int featureID) { + switch (featureID) { + case PointerAnalysisPackage.EJAVA_CLASS_INSTANCE__JAVA_CLASS: + return javaClass != null; + } + return super.eIsSet(featureID); + } + +} //EJavaClassInstanceImpl \ No newline at end of file diff --git a/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/pointerAnalysis/impl/ELocalPointerImpl.java b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/pointerAnalysis/impl/ELocalPointerImpl.java new file mode 100644 index 000000000..31e28e314 --- /dev/null +++ b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/pointerAnalysis/impl/ELocalPointerImpl.java @@ -0,0 +1,223 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java.pointerAnalysis.impl; + +import com.ibm.wala.ecore.java.EJavaMethod; + +import com.ibm.wala.ecore.java.pointerAnalysis.ELocalPointer; +import com.ibm.wala.ecore.java.pointerAnalysis.PointerAnalysisPackage; + +import org.eclipse.emf.common.notify.Notification; + +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.InternalEObject; + +import org.eclipse.emf.ecore.impl.ENotificationImpl; + +/** + * + * An implementation of the model object 'ELocal Pointer'. + * + *

                              + * The following features are implemented: + *

                                + *
                              • {@link com.ibm.wala.ecore.java.pointerAnalysis.impl.ELocalPointerImpl#getValueNumber Value Number}
                              • + *
                              • {@link com.ibm.wala.ecore.java.pointerAnalysis.impl.ELocalPointerImpl#getJavaMethod Java Method}
                              • + *
                              + *

                              + * + * @generated + */ +public class ELocalPointerImpl extends EPointerImpl implements ELocalPointer { + /** + * The default value of the '{@link #getValueNumber() Value Number}' attribute. + * + * + * @see #getValueNumber() + * @generated + * @ordered + */ + protected static final int VALUE_NUMBER_EDEFAULT = 0; + + /** + * The cached value of the '{@link #getValueNumber() Value Number}' attribute. + * + * + * @see #getValueNumber() + * @generated + * @ordered + */ + protected int valueNumber = VALUE_NUMBER_EDEFAULT; + + /** + * The cached value of the '{@link #getJavaMethod() Java Method}' reference. + * + * + * @see #getJavaMethod() + * @generated + * @ordered + */ + protected EJavaMethod javaMethod = null; + + /** + * + * + * @generated + */ + protected ELocalPointerImpl() { + super(); + } + + /** + * + * + * @generated + */ + protected EClass eStaticClass() { + return PointerAnalysisPackage.Literals.ELOCAL_POINTER; + } + + /** + * + * + * @generated + */ + public int getValueNumber() { + return valueNumber; + } + + /** + * + * + * @generated + */ + public void setValueNumber(int newValueNumber) { + int oldValueNumber = valueNumber; + valueNumber = newValueNumber; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, PointerAnalysisPackage.ELOCAL_POINTER__VALUE_NUMBER, oldValueNumber, valueNumber)); + } + + /** + * + * + * @generated + */ + public EJavaMethod getJavaMethod() { + if (javaMethod != null && javaMethod.eIsProxy()) { + InternalEObject oldJavaMethod = (InternalEObject)javaMethod; + javaMethod = (EJavaMethod)eResolveProxy(oldJavaMethod); + if (javaMethod != oldJavaMethod) { + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.RESOLVE, PointerAnalysisPackage.ELOCAL_POINTER__JAVA_METHOD, oldJavaMethod, javaMethod)); + } + } + return javaMethod; + } + + /** + * + * + * @generated + */ + public EJavaMethod basicGetJavaMethod() { + return javaMethod; + } + + /** + * + * + * @generated + */ + public void setJavaMethod(EJavaMethod newJavaMethod) { + EJavaMethod oldJavaMethod = javaMethod; + javaMethod = newJavaMethod; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, PointerAnalysisPackage.ELOCAL_POINTER__JAVA_METHOD, oldJavaMethod, javaMethod)); + } + + /** + * + * + * @generated + */ + public Object eGet(int featureID, boolean resolve, boolean coreType) { + switch (featureID) { + case PointerAnalysisPackage.ELOCAL_POINTER__VALUE_NUMBER: + return new Integer(getValueNumber()); + case PointerAnalysisPackage.ELOCAL_POINTER__JAVA_METHOD: + if (resolve) return getJavaMethod(); + return basicGetJavaMethod(); + } + return super.eGet(featureID, resolve, coreType); + } + + /** + * + * + * @generated + */ + public void eSet(int featureID, Object newValue) { + switch (featureID) { + case PointerAnalysisPackage.ELOCAL_POINTER__VALUE_NUMBER: + setValueNumber(((Integer)newValue).intValue()); + return; + case PointerAnalysisPackage.ELOCAL_POINTER__JAVA_METHOD: + setJavaMethod((EJavaMethod)newValue); + return; + } + super.eSet(featureID, newValue); + } + + /** + * + * + * @generated + */ + public void eUnset(int featureID) { + switch (featureID) { + case PointerAnalysisPackage.ELOCAL_POINTER__VALUE_NUMBER: + setValueNumber(VALUE_NUMBER_EDEFAULT); + return; + case PointerAnalysisPackage.ELOCAL_POINTER__JAVA_METHOD: + setJavaMethod((EJavaMethod)null); + return; + } + super.eUnset(featureID); + } + + /** + * + * + * @generated + */ + public boolean eIsSet(int featureID) { + switch (featureID) { + case PointerAnalysisPackage.ELOCAL_POINTER__VALUE_NUMBER: + return valueNumber != VALUE_NUMBER_EDEFAULT; + case PointerAnalysisPackage.ELOCAL_POINTER__JAVA_METHOD: + return javaMethod != null; + } + return super.eIsSet(featureID); + } + + /** + * + * + * @generated + */ + public String toString() { + if (eIsProxy()) return super.toString(); + + StringBuffer result = new StringBuffer(super.toString()); + result.append(" (valueNumber: "); + result.append(valueNumber); + result.append(')'); + return result.toString(); + } + +} //ELocalPointerImpl \ No newline at end of file diff --git a/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/pointerAnalysis/impl/EPointerImpl.java b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/pointerAnalysis/impl/EPointerImpl.java new file mode 100644 index 000000000..593f7626f --- /dev/null +++ b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/pointerAnalysis/impl/EPointerImpl.java @@ -0,0 +1,44 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java.pointerAnalysis.impl; + +import com.ibm.wala.ecore.java.pointerAnalysis.EPointer; +import com.ibm.wala.ecore.java.pointerAnalysis.PointerAnalysisPackage; + +import org.eclipse.emf.ecore.EClass; + +import org.eclipse.emf.ecore.impl.EObjectImpl; + +/** + * + * An implementation of the model object 'EPointer'. + * + *

                              + *

                              + * + * @generated + */ +public abstract class EPointerImpl extends EObjectImpl implements EPointer { + /** + * + * + * @generated + */ + protected EPointerImpl() { + super(); + } + + /** + * + * + * @generated + */ + protected EClass eStaticClass() { + return PointerAnalysisPackage.Literals.EPOINTER; + } + +} //EPointerImpl \ No newline at end of file diff --git a/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/pointerAnalysis/impl/EReturnValuePointerImpl.java b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/pointerAnalysis/impl/EReturnValuePointerImpl.java new file mode 100644 index 000000000..4b3219803 --- /dev/null +++ b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/pointerAnalysis/impl/EReturnValuePointerImpl.java @@ -0,0 +1,223 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java.pointerAnalysis.impl; + +import com.ibm.wala.ecore.java.EJavaMethod; + +import com.ibm.wala.ecore.java.pointerAnalysis.EReturnValuePointer; +import com.ibm.wala.ecore.java.pointerAnalysis.PointerAnalysisPackage; + +import org.eclipse.emf.common.notify.Notification; + +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.InternalEObject; + +import org.eclipse.emf.ecore.impl.ENotificationImpl; + +/** + * + * An implementation of the model object 'EReturn Value Pointer'. + * + *

                              + * The following features are implemented: + *

                                + *
                              • {@link com.ibm.wala.ecore.java.pointerAnalysis.impl.EReturnValuePointerImpl#isIsExceptionalReturnValue Is Exceptional Return Value}
                              • + *
                              • {@link com.ibm.wala.ecore.java.pointerAnalysis.impl.EReturnValuePointerImpl#getJavaMethod Java Method}
                              • + *
                              + *

                              + * + * @generated + */ +public class EReturnValuePointerImpl extends EPointerImpl implements EReturnValuePointer { + /** + * The default value of the '{@link #isIsExceptionalReturnValue() Is Exceptional Return Value}' attribute. + * + * + * @see #isIsExceptionalReturnValue() + * @generated + * @ordered + */ + protected static final boolean IS_EXCEPTIONAL_RETURN_VALUE_EDEFAULT = false; + + /** + * The cached value of the '{@link #isIsExceptionalReturnValue() Is Exceptional Return Value}' attribute. + * + * + * @see #isIsExceptionalReturnValue() + * @generated + * @ordered + */ + protected boolean isExceptionalReturnValue = IS_EXCEPTIONAL_RETURN_VALUE_EDEFAULT; + + /** + * The cached value of the '{@link #getJavaMethod() Java Method}' reference. + * + * + * @see #getJavaMethod() + * @generated + * @ordered + */ + protected EJavaMethod javaMethod = null; + + /** + * + * + * @generated + */ + protected EReturnValuePointerImpl() { + super(); + } + + /** + * + * + * @generated + */ + protected EClass eStaticClass() { + return PointerAnalysisPackage.Literals.ERETURN_VALUE_POINTER; + } + + /** + * + * + * @generated + */ + public boolean isIsExceptionalReturnValue() { + return isExceptionalReturnValue; + } + + /** + * + * + * @generated + */ + public void setIsExceptionalReturnValue(boolean newIsExceptionalReturnValue) { + boolean oldIsExceptionalReturnValue = isExceptionalReturnValue; + isExceptionalReturnValue = newIsExceptionalReturnValue; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, PointerAnalysisPackage.ERETURN_VALUE_POINTER__IS_EXCEPTIONAL_RETURN_VALUE, oldIsExceptionalReturnValue, isExceptionalReturnValue)); + } + + /** + * + * + * @generated + */ + public EJavaMethod getJavaMethod() { + if (javaMethod != null && javaMethod.eIsProxy()) { + InternalEObject oldJavaMethod = (InternalEObject)javaMethod; + javaMethod = (EJavaMethod)eResolveProxy(oldJavaMethod); + if (javaMethod != oldJavaMethod) { + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.RESOLVE, PointerAnalysisPackage.ERETURN_VALUE_POINTER__JAVA_METHOD, oldJavaMethod, javaMethod)); + } + } + return javaMethod; + } + + /** + * + * + * @generated + */ + public EJavaMethod basicGetJavaMethod() { + return javaMethod; + } + + /** + * + * + * @generated + */ + public void setJavaMethod(EJavaMethod newJavaMethod) { + EJavaMethod oldJavaMethod = javaMethod; + javaMethod = newJavaMethod; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, PointerAnalysisPackage.ERETURN_VALUE_POINTER__JAVA_METHOD, oldJavaMethod, javaMethod)); + } + + /** + * + * + * @generated + */ + public Object eGet(int featureID, boolean resolve, boolean coreType) { + switch (featureID) { + case PointerAnalysisPackage.ERETURN_VALUE_POINTER__IS_EXCEPTIONAL_RETURN_VALUE: + return isIsExceptionalReturnValue() ? Boolean.TRUE : Boolean.FALSE; + case PointerAnalysisPackage.ERETURN_VALUE_POINTER__JAVA_METHOD: + if (resolve) return getJavaMethod(); + return basicGetJavaMethod(); + } + return super.eGet(featureID, resolve, coreType); + } + + /** + * + * + * @generated + */ + public void eSet(int featureID, Object newValue) { + switch (featureID) { + case PointerAnalysisPackage.ERETURN_VALUE_POINTER__IS_EXCEPTIONAL_RETURN_VALUE: + setIsExceptionalReturnValue(((Boolean)newValue).booleanValue()); + return; + case PointerAnalysisPackage.ERETURN_VALUE_POINTER__JAVA_METHOD: + setJavaMethod((EJavaMethod)newValue); + return; + } + super.eSet(featureID, newValue); + } + + /** + * + * + * @generated + */ + public void eUnset(int featureID) { + switch (featureID) { + case PointerAnalysisPackage.ERETURN_VALUE_POINTER__IS_EXCEPTIONAL_RETURN_VALUE: + setIsExceptionalReturnValue(IS_EXCEPTIONAL_RETURN_VALUE_EDEFAULT); + return; + case PointerAnalysisPackage.ERETURN_VALUE_POINTER__JAVA_METHOD: + setJavaMethod((EJavaMethod)null); + return; + } + super.eUnset(featureID); + } + + /** + * + * + * @generated + */ + public boolean eIsSet(int featureID) { + switch (featureID) { + case PointerAnalysisPackage.ERETURN_VALUE_POINTER__IS_EXCEPTIONAL_RETURN_VALUE: + return isExceptionalReturnValue != IS_EXCEPTIONAL_RETURN_VALUE_EDEFAULT; + case PointerAnalysisPackage.ERETURN_VALUE_POINTER__JAVA_METHOD: + return javaMethod != null; + } + return super.eIsSet(featureID); + } + + /** + * + * + * @generated + */ + public String toString() { + if (eIsProxy()) return super.toString(); + + StringBuffer result = new StringBuffer(super.toString()); + result.append(" (isExceptionalReturnValue: "); + result.append(isExceptionalReturnValue); + result.append(')'); + return result.toString(); + } + +} //EReturnValuePointerImpl \ No newline at end of file diff --git a/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/pointerAnalysis/impl/EStaticFieldImpl.java b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/pointerAnalysis/impl/EStaticFieldImpl.java new file mode 100644 index 000000000..0a83af731 --- /dev/null +++ b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/pointerAnalysis/impl/EStaticFieldImpl.java @@ -0,0 +1,160 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java.pointerAnalysis.impl; + +import com.ibm.wala.ecore.java.pointerAnalysis.EStaticField; +import com.ibm.wala.ecore.java.pointerAnalysis.PointerAnalysisPackage; + +import org.eclipse.emf.common.notify.Notification; + +import org.eclipse.emf.ecore.EClass; + +import org.eclipse.emf.ecore.impl.ENotificationImpl; + +/** + * + * An implementation of the model object 'EStatic Field'. + * + *

                              + * The following features are implemented: + *

                                + *
                              • {@link com.ibm.wala.ecore.java.pointerAnalysis.impl.EStaticFieldImpl#getFieldName Field Name}
                              • + *
                              + *

                              + * + * @generated + */ +public class EStaticFieldImpl extends EPointerImpl implements EStaticField { + /** + * The default value of the '{@link #getFieldName() Field Name}' attribute. + * + * + * @see #getFieldName() + * @generated + * @ordered + */ + protected static final String FIELD_NAME_EDEFAULT = null; + + /** + * The cached value of the '{@link #getFieldName() Field Name}' attribute. + * + * + * @see #getFieldName() + * @generated + * @ordered + */ + protected String fieldName = FIELD_NAME_EDEFAULT; + + /** + * + * + * @generated + */ + protected EStaticFieldImpl() { + super(); + } + + /** + * + * + * @generated + */ + protected EClass eStaticClass() { + return PointerAnalysisPackage.Literals.ESTATIC_FIELD; + } + + /** + * + * + * @generated + */ + public String getFieldName() { + return fieldName; + } + + /** + * + * + * @generated + */ + public void setFieldName(String newFieldName) { + String oldFieldName = fieldName; + fieldName = newFieldName; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, PointerAnalysisPackage.ESTATIC_FIELD__FIELD_NAME, oldFieldName, fieldName)); + } + + /** + * + * + * @generated + */ + public Object eGet(int featureID, boolean resolve, boolean coreType) { + switch (featureID) { + case PointerAnalysisPackage.ESTATIC_FIELD__FIELD_NAME: + return getFieldName(); + } + return super.eGet(featureID, resolve, coreType); + } + + /** + * + * + * @generated + */ + public void eSet(int featureID, Object newValue) { + switch (featureID) { + case PointerAnalysisPackage.ESTATIC_FIELD__FIELD_NAME: + setFieldName((String)newValue); + return; + } + super.eSet(featureID, newValue); + } + + /** + * + * + * @generated + */ + public void eUnset(int featureID) { + switch (featureID) { + case PointerAnalysisPackage.ESTATIC_FIELD__FIELD_NAME: + setFieldName(FIELD_NAME_EDEFAULT); + return; + } + super.eUnset(featureID); + } + + /** + * + * + * @generated + */ + public boolean eIsSet(int featureID) { + switch (featureID) { + case PointerAnalysisPackage.ESTATIC_FIELD__FIELD_NAME: + return FIELD_NAME_EDEFAULT == null ? fieldName != null : !FIELD_NAME_EDEFAULT.equals(fieldName); + } + return super.eIsSet(featureID); + } + + /** + * + * + * @generated + */ + public String toString() { + if (eIsProxy()) return super.toString(); + + StringBuffer result = new StringBuffer(super.toString()); + result.append(" (fieldName: "); + result.append(fieldName); + result.append(')'); + return result.toString(); + } + +} //EStaticFieldImpl \ No newline at end of file diff --git a/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/pointerAnalysis/impl/PointerAnalysisFactoryImpl.java b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/pointerAnalysis/impl/PointerAnalysisFactoryImpl.java new file mode 100644 index 000000000..067d6ee56 --- /dev/null +++ b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/pointerAnalysis/impl/PointerAnalysisFactoryImpl.java @@ -0,0 +1,163 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java.pointerAnalysis.impl; + +import com.ibm.wala.ecore.java.pointerAnalysis.*; + +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EPackage; + +import org.eclipse.emf.ecore.impl.EFactoryImpl; + +import org.eclipse.emf.ecore.plugin.EcorePlugin; + +/** + * + * An implementation of the model Factory. + * + * @generated + */ +public class PointerAnalysisFactoryImpl extends EFactoryImpl implements PointerAnalysisFactory { + /** + * Creates the default factory implementation. + * + * + * @generated + */ + public static PointerAnalysisFactory init() { + try { + PointerAnalysisFactory thePointerAnalysisFactory = (PointerAnalysisFactory)EPackage.Registry.INSTANCE.getEFactory("http:///com/ibm/wala/wala.ecore.java.pointerAnalysis"); + if (thePointerAnalysisFactory != null) { + return thePointerAnalysisFactory; + } + } + catch (Exception exception) { + EcorePlugin.INSTANCE.log(exception); + } + return new PointerAnalysisFactoryImpl(); + } + + /** + * Creates an instance of the factory. + * + * + * @generated + */ + public PointerAnalysisFactoryImpl() { + super(); + } + + /** + * + * + * @generated + */ + public EObject create(EClass eClass) { + switch (eClass.getClassifierID()) { + case PointerAnalysisPackage.EINSTANCE_FIELD: return createEInstanceField(); + case PointerAnalysisPackage.EARRAY_CONTENTS: return createEArrayContents(); + case PointerAnalysisPackage.ESTATIC_FIELD: return createEStaticField(); + case PointerAnalysisPackage.ELOCAL_POINTER: return createELocalPointer(); + case PointerAnalysisPackage.ERETURN_VALUE_POINTER: return createEReturnValuePointer(); + case PointerAnalysisPackage.EJAVA_CLASS_INSTANCE: return createEJavaClassInstance(); + case PointerAnalysisPackage.EHEAP_GRAPH: return createEHeapGraph(); + default: + throw new IllegalArgumentException("The class '" + eClass.getName() + "' is not a valid classifier"); + } + } + + /** + * + * + * @generated + */ + public EInstanceField createEInstanceField() { + EInstanceFieldImpl eInstanceField = new EInstanceFieldImpl(); + return eInstanceField; + } + + /** + * + * + * @generated + */ + public EArrayContents createEArrayContents() { + EArrayContentsImpl eArrayContents = new EArrayContentsImpl(); + return eArrayContents; + } + + /** + * + * + * @generated + */ + public EStaticField createEStaticField() { + EStaticFieldImpl eStaticField = new EStaticFieldImpl(); + return eStaticField; + } + + /** + * + * + * @generated + */ + public ELocalPointer createELocalPointer() { + ELocalPointerImpl eLocalPointer = new ELocalPointerImpl(); + return eLocalPointer; + } + + /** + * + * + * @generated + */ + public EReturnValuePointer createEReturnValuePointer() { + EReturnValuePointerImpl eReturnValuePointer = new EReturnValuePointerImpl(); + return eReturnValuePointer; + } + + /** + * + * + * @generated + */ + public EJavaClassInstance createEJavaClassInstance() { + EJavaClassInstanceImpl eJavaClassInstance = new EJavaClassInstanceImpl(); + return eJavaClassInstance; + } + + /** + * + * + * @generated + */ + public EHeapGraph createEHeapGraph() { + EHeapGraphImpl eHeapGraph = new EHeapGraphImpl(); + return eHeapGraph; + } + + /** + * + * + * @generated + */ + public PointerAnalysisPackage getPointerAnalysisPackage() { + return (PointerAnalysisPackage)getEPackage(); + } + + /** + * + * + * @deprecated + * @generated + */ + public static PointerAnalysisPackage getPackage() { + return PointerAnalysisPackage.eINSTANCE; + } + +} //PointerAnalysisFactoryImpl diff --git a/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/pointerAnalysis/impl/PointerAnalysisPackageImpl.java b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/pointerAnalysis/impl/PointerAnalysisPackageImpl.java new file mode 100644 index 000000000..17a463d50 --- /dev/null +++ b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/pointerAnalysis/impl/PointerAnalysisPackageImpl.java @@ -0,0 +1,496 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java.pointerAnalysis.impl; + +import com.ibm.wala.ecore.common.CommonPackage; + +import com.ibm.wala.ecore.common.impl.CommonPackageImpl; + +import com.ibm.wala.ecore.graph.GraphPackage; + +import com.ibm.wala.ecore.graph.impl.GraphPackageImpl; + +import com.ibm.wala.ecore.j2ee.scope.J2EEScopePackage; + +import com.ibm.wala.ecore.j2ee.scope.impl.J2EEScopePackageImpl; + +import com.ibm.wala.ecore.java.JavaPackage; + +import com.ibm.wala.ecore.java.callGraph.CallGraphPackage; + +import com.ibm.wala.ecore.java.callGraph.impl.CallGraphPackageImpl; + +import com.ibm.wala.ecore.java.impl.JavaPackageImpl; + +import com.ibm.wala.ecore.java.pointerAnalysis.EArrayContents; +import com.ibm.wala.ecore.java.pointerAnalysis.EHeapGraph; +import com.ibm.wala.ecore.java.pointerAnalysis.EInstance; +import com.ibm.wala.ecore.java.pointerAnalysis.EInstanceField; +import com.ibm.wala.ecore.java.pointerAnalysis.EJavaClassInstance; +import com.ibm.wala.ecore.java.pointerAnalysis.ELocalPointer; +import com.ibm.wala.ecore.java.pointerAnalysis.EPointer; +import com.ibm.wala.ecore.java.pointerAnalysis.EReturnValuePointer; +import com.ibm.wala.ecore.java.pointerAnalysis.EStaticField; +import com.ibm.wala.ecore.java.pointerAnalysis.PointerAnalysisFactory; +import com.ibm.wala.ecore.java.pointerAnalysis.PointerAnalysisPackage; + +import com.ibm.wala.ecore.java.scope.JavaScopePackage; + +import com.ibm.wala.ecore.java.scope.impl.JavaScopePackageImpl; + +import com.ibm.wala.ecore.perf.PerfPackage; + +import com.ibm.wala.ecore.perf.impl.PerfPackageImpl; + +import com.ibm.wala.ecore.regex.RegexPackage; + +import com.ibm.wala.ecore.regex.impl.RegexPackageImpl; + +import org.eclipse.emf.ecore.EAttribute; +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EPackage; +import org.eclipse.emf.ecore.EReference; + +import org.eclipse.emf.ecore.impl.EPackageImpl; + +/** + * + * An implementation of the model Package. + * + * @generated + */ +public class PointerAnalysisPackageImpl extends EPackageImpl implements PointerAnalysisPackage { + /** + * + * + * @generated + */ + private EClass ePointerEClass = null; + + /** + * + * + * @generated + */ + private EClass eInstanceFieldEClass = null; + + /** + * + * + * @generated + */ + private EClass eArrayContentsEClass = null; + + /** + * + * + * @generated + */ + private EClass eStaticFieldEClass = null; + + /** + * + * + * @generated + */ + private EClass eLocalPointerEClass = null; + + /** + * + * + * @generated + */ + private EClass eReturnValuePointerEClass = null; + + /** + * + * + * @generated + */ + private EClass eInstanceEClass = null; + + /** + * + * + * @generated + */ + private EClass eJavaClassInstanceEClass = null; + + /** + * + * + * @generated + */ + private EClass eHeapGraphEClass = null; + + /** + * Creates an instance of the model Package, registered with + * {@link org.eclipse.emf.ecore.EPackage.Registry EPackage.Registry} by the package + * package URI value. + *

                              Note: the correct way to create the package is via the static + * factory method {@link #init init()}, which also performs + * initialization of the package, or returns the registered package, + * if one already exists. + * + * + * @see org.eclipse.emf.ecore.EPackage.Registry + * @see com.ibm.wala.ecore.java.pointerAnalysis.PointerAnalysisPackage#eNS_URI + * @see #init() + * @generated + */ + private PointerAnalysisPackageImpl() { + super(eNS_URI, PointerAnalysisFactory.eINSTANCE); + } + + /** + * + * + * @generated + */ + private static boolean isInited = false; + + /** + * Creates, registers, and initializes the Package for this + * model, and for any others upon which it depends. Simple + * dependencies are satisfied by calling this method on all + * dependent packages before doing anything else. This method drives + * initialization for interdependent packages directly, in parallel + * with this package, itself. + *

                              Of this package and its interdependencies, all packages which + * have not yet been registered by their URI values are first created + * and registered. The packages are then initialized in two steps: + * meta-model objects for all of the packages are created before any + * are initialized, since one package's meta-model objects may refer to + * those of another. + *

                              Invocation of this method will not affect any packages that have + * already been initialized. + * + * + * @see #eNS_URI + * @see #createPackageContents() + * @see #initializePackageContents() + * @generated + */ + public static PointerAnalysisPackage init() { + if (isInited) return (PointerAnalysisPackage)EPackage.Registry.INSTANCE.getEPackage(PointerAnalysisPackage.eNS_URI); + + // Obtain or create and register package + PointerAnalysisPackageImpl thePointerAnalysisPackage = (PointerAnalysisPackageImpl)(EPackage.Registry.INSTANCE.getEPackage(eNS_URI) instanceof PointerAnalysisPackageImpl ? EPackage.Registry.INSTANCE.getEPackage(eNS_URI) : new PointerAnalysisPackageImpl()); + + isInited = true; + + // Obtain or create and register interdependencies + GraphPackageImpl theGraphPackage = (GraphPackageImpl)(EPackage.Registry.INSTANCE.getEPackage(GraphPackage.eNS_URI) instanceof GraphPackageImpl ? EPackage.Registry.INSTANCE.getEPackage(GraphPackage.eNS_URI) : GraphPackage.eINSTANCE); + CommonPackageImpl theCommonPackage = (CommonPackageImpl)(EPackage.Registry.INSTANCE.getEPackage(CommonPackage.eNS_URI) instanceof CommonPackageImpl ? EPackage.Registry.INSTANCE.getEPackage(CommonPackage.eNS_URI) : CommonPackage.eINSTANCE); + RegexPackageImpl theRegexPackage = (RegexPackageImpl)(EPackage.Registry.INSTANCE.getEPackage(RegexPackage.eNS_URI) instanceof RegexPackageImpl ? EPackage.Registry.INSTANCE.getEPackage(RegexPackage.eNS_URI) : RegexPackage.eINSTANCE); + PerfPackageImpl thePerfPackage = (PerfPackageImpl)(EPackage.Registry.INSTANCE.getEPackage(PerfPackage.eNS_URI) instanceof PerfPackageImpl ? EPackage.Registry.INSTANCE.getEPackage(PerfPackage.eNS_URI) : PerfPackage.eINSTANCE); + JavaPackageImpl theJavaPackage = (JavaPackageImpl)(EPackage.Registry.INSTANCE.getEPackage(JavaPackage.eNS_URI) instanceof JavaPackageImpl ? EPackage.Registry.INSTANCE.getEPackage(JavaPackage.eNS_URI) : JavaPackage.eINSTANCE); + CallGraphPackageImpl theCallGraphPackage = (CallGraphPackageImpl)(EPackage.Registry.INSTANCE.getEPackage(CallGraphPackage.eNS_URI) instanceof CallGraphPackageImpl ? EPackage.Registry.INSTANCE.getEPackage(CallGraphPackage.eNS_URI) : CallGraphPackage.eINSTANCE); + JavaScopePackageImpl theJavaScopePackage = (JavaScopePackageImpl)(EPackage.Registry.INSTANCE.getEPackage(JavaScopePackage.eNS_URI) instanceof JavaScopePackageImpl ? EPackage.Registry.INSTANCE.getEPackage(JavaScopePackage.eNS_URI) : JavaScopePackage.eINSTANCE); + J2EEScopePackageImpl theJ2EEScopePackage = (J2EEScopePackageImpl)(EPackage.Registry.INSTANCE.getEPackage(J2EEScopePackage.eNS_URI) instanceof J2EEScopePackageImpl ? EPackage.Registry.INSTANCE.getEPackage(J2EEScopePackage.eNS_URI) : J2EEScopePackage.eINSTANCE); + + // Create package meta-data objects + thePointerAnalysisPackage.createPackageContents(); + theGraphPackage.createPackageContents(); + theCommonPackage.createPackageContents(); + theRegexPackage.createPackageContents(); + thePerfPackage.createPackageContents(); + theJavaPackage.createPackageContents(); + theCallGraphPackage.createPackageContents(); + theJavaScopePackage.createPackageContents(); + theJ2EEScopePackage.createPackageContents(); + + // Initialize created meta-data + thePointerAnalysisPackage.initializePackageContents(); + theGraphPackage.initializePackageContents(); + theCommonPackage.initializePackageContents(); + theRegexPackage.initializePackageContents(); + thePerfPackage.initializePackageContents(); + theJavaPackage.initializePackageContents(); + theCallGraphPackage.initializePackageContents(); + theJavaScopePackage.initializePackageContents(); + theJ2EEScopePackage.initializePackageContents(); + + // Mark meta-data to indicate it can't be changed + thePointerAnalysisPackage.freeze(); + + return thePointerAnalysisPackage; + } + + /** + * + * + * @generated + */ + public EClass getEPointer() { + return ePointerEClass; + } + + /** + * + * + * @generated + */ + public EClass getEInstanceField() { + return eInstanceFieldEClass; + } + + /** + * + * + * @generated + */ + public EAttribute getEInstanceField_FieldName() { + return (EAttribute)eInstanceFieldEClass.getEStructuralFeatures().get(0); + } + + /** + * + * + * @generated + */ + public EClass getEArrayContents() { + return eArrayContentsEClass; + } + + /** + * + * + * @generated + */ + public EReference getEArrayContents_JavaClass() { + return (EReference)eArrayContentsEClass.getEStructuralFeatures().get(0); + } + + /** + * + * + * @generated + */ + public EClass getEStaticField() { + return eStaticFieldEClass; + } + + /** + * + * + * @generated + */ + public EAttribute getEStaticField_FieldName() { + return (EAttribute)eStaticFieldEClass.getEStructuralFeatures().get(0); + } + + /** + * + * + * @generated + */ + public EClass getELocalPointer() { + return eLocalPointerEClass; + } + + /** + * + * + * @generated + */ + public EAttribute getELocalPointer_ValueNumber() { + return (EAttribute)eLocalPointerEClass.getEStructuralFeatures().get(0); + } + + /** + * + * + * @generated + */ + public EReference getELocalPointer_JavaMethod() { + return (EReference)eLocalPointerEClass.getEStructuralFeatures().get(1); + } + + /** + * + * + * @generated + */ + public EClass getEReturnValuePointer() { + return eReturnValuePointerEClass; + } + + /** + * + * + * @generated + */ + public EAttribute getEReturnValuePointer_IsExceptionalReturnValue() { + return (EAttribute)eReturnValuePointerEClass.getEStructuralFeatures().get(0); + } + + /** + * + * + * @generated + */ + public EReference getEReturnValuePointer_JavaMethod() { + return (EReference)eReturnValuePointerEClass.getEStructuralFeatures().get(1); + } + + /** + * + * + * @generated + */ + public EClass getEInstance() { + return eInstanceEClass; + } + + /** + * + * + * @generated + */ + public EClass getEJavaClassInstance() { + return eJavaClassInstanceEClass; + } + + /** + * + * + * @generated + */ + public EReference getEJavaClassInstance_JavaClass() { + return (EReference)eJavaClassInstanceEClass.getEStructuralFeatures().get(0); + } + + /** + * + * + * @generated + */ + public EClass getEHeapGraph() { + return eHeapGraphEClass; + } + + /** + * + * + * @generated + */ + public PointerAnalysisFactory getPointerAnalysisFactory() { + return (PointerAnalysisFactory)getEFactoryInstance(); + } + + /** + * + * + * @generated + */ + private boolean isCreated = false; + + /** + * Creates the meta-model objects for the package. This method is + * guarded to have no affect on any invocation but its first. + * + * + * @generated + */ + public void createPackageContents() { + if (isCreated) return; + isCreated = true; + + // Create classes and their features + ePointerEClass = createEClass(EPOINTER); + + eInstanceFieldEClass = createEClass(EINSTANCE_FIELD); + createEAttribute(eInstanceFieldEClass, EINSTANCE_FIELD__FIELD_NAME); + + eArrayContentsEClass = createEClass(EARRAY_CONTENTS); + createEReference(eArrayContentsEClass, EARRAY_CONTENTS__JAVA_CLASS); + + eStaticFieldEClass = createEClass(ESTATIC_FIELD); + createEAttribute(eStaticFieldEClass, ESTATIC_FIELD__FIELD_NAME); + + eLocalPointerEClass = createEClass(ELOCAL_POINTER); + createEAttribute(eLocalPointerEClass, ELOCAL_POINTER__VALUE_NUMBER); + createEReference(eLocalPointerEClass, ELOCAL_POINTER__JAVA_METHOD); + + eReturnValuePointerEClass = createEClass(ERETURN_VALUE_POINTER); + createEAttribute(eReturnValuePointerEClass, ERETURN_VALUE_POINTER__IS_EXCEPTIONAL_RETURN_VALUE); + createEReference(eReturnValuePointerEClass, ERETURN_VALUE_POINTER__JAVA_METHOD); + + eInstanceEClass = createEClass(EINSTANCE); + + eJavaClassInstanceEClass = createEClass(EJAVA_CLASS_INSTANCE); + createEReference(eJavaClassInstanceEClass, EJAVA_CLASS_INSTANCE__JAVA_CLASS); + + eHeapGraphEClass = createEClass(EHEAP_GRAPH); + } + + /** + * + * + * @generated + */ + private boolean isInitialized = false; + + /** + * Complete the initialization of the package and its meta-model. This + * method is guarded to have no affect on any invocation but its first. + * + * + * @generated + */ + public void initializePackageContents() { + if (isInitialized) return; + isInitialized = true; + + // Initialize package + setName(eNAME); + setNsPrefix(eNS_PREFIX); + setNsURI(eNS_URI); + + // Obtain other dependent packages + JavaPackage theJavaPackage = (JavaPackage)EPackage.Registry.INSTANCE.getEPackage(JavaPackage.eNS_URI); + GraphPackage theGraphPackage = (GraphPackage)EPackage.Registry.INSTANCE.getEPackage(GraphPackage.eNS_URI); + + // Add supertypes to classes + eInstanceFieldEClass.getESuperTypes().add(this.getEPointer()); + eArrayContentsEClass.getESuperTypes().add(this.getEPointer()); + eStaticFieldEClass.getESuperTypes().add(this.getEPointer()); + eLocalPointerEClass.getESuperTypes().add(this.getEPointer()); + eReturnValuePointerEClass.getESuperTypes().add(this.getEPointer()); + eJavaClassInstanceEClass.getESuperTypes().add(this.getEInstance()); + eHeapGraphEClass.getESuperTypes().add(theGraphPackage.getEGraph()); + + // Initialize classes and features; add operations and parameters + initEClass(ePointerEClass, EPointer.class, "EPointer", IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); + + initEClass(eInstanceFieldEClass, EInstanceField.class, "EInstanceField", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); + initEAttribute(getEInstanceField_FieldName(), ecorePackage.getEString(), "fieldName", null, 0, 1, EInstanceField.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); + + initEClass(eArrayContentsEClass, EArrayContents.class, "EArrayContents", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); + initEReference(getEArrayContents_JavaClass(), theJavaPackage.getEJavaClass(), null, "javaClass", null, 1, 1, EArrayContents.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_COMPOSITE, IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); + + initEClass(eStaticFieldEClass, EStaticField.class, "EStaticField", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); + initEAttribute(getEStaticField_FieldName(), ecorePackage.getEString(), "fieldName", null, 0, 1, EStaticField.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); + + initEClass(eLocalPointerEClass, ELocalPointer.class, "ELocalPointer", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); + initEAttribute(getELocalPointer_ValueNumber(), ecorePackage.getEInt(), "valueNumber", null, 1, 1, ELocalPointer.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); + initEReference(getELocalPointer_JavaMethod(), theJavaPackage.getEJavaMethod(), null, "javaMethod", null, 1, 1, ELocalPointer.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_COMPOSITE, IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); + + initEClass(eReturnValuePointerEClass, EReturnValuePointer.class, "EReturnValuePointer", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); + initEAttribute(getEReturnValuePointer_IsExceptionalReturnValue(), ecorePackage.getEBoolean(), "isExceptionalReturnValue", null, 0, 1, EReturnValuePointer.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); + initEReference(getEReturnValuePointer_JavaMethod(), theJavaPackage.getEJavaMethod(), null, "javaMethod", null, 1, 1, EReturnValuePointer.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_COMPOSITE, IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); + + initEClass(eInstanceEClass, EInstance.class, "EInstance", IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); + + initEClass(eJavaClassInstanceEClass, EJavaClassInstance.class, "EJavaClassInstance", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); + initEReference(getEJavaClassInstance_JavaClass(), theJavaPackage.getEJavaClass(), null, "javaClass", null, 1, 1, EJavaClassInstance.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_COMPOSITE, IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); + + initEClass(eHeapGraphEClass, EHeapGraph.class, "EHeapGraph", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); + } + +} //PointerAnalysisPackageImpl diff --git a/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/pointerAnalysis/util/PointerAnalysisAdapterFactory.java b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/pointerAnalysis/util/PointerAnalysisAdapterFactory.java new file mode 100644 index 000000000..d61400e1f --- /dev/null +++ b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/pointerAnalysis/util/PointerAnalysisAdapterFactory.java @@ -0,0 +1,275 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java.pointerAnalysis.util; + +import com.ibm.wala.ecore.graph.EGraph; + +import com.ibm.wala.ecore.java.pointerAnalysis.*; + +import org.eclipse.emf.common.notify.Adapter; +import org.eclipse.emf.common.notify.Notifier; + +import org.eclipse.emf.common.notify.impl.AdapterFactoryImpl; + +import org.eclipse.emf.ecore.EObject; + +/** + * + * The Adapter Factory for the model. + * It provides an adapter createXXX method for each class of the model. + * + * @see com.ibm.wala.ecore.java.pointerAnalysis.PointerAnalysisPackage + * @generated + */ +public class PointerAnalysisAdapterFactory extends AdapterFactoryImpl { + /** + * The cached model package. + * + * + * @generated + */ + protected static PointerAnalysisPackage modelPackage; + + /** + * Creates an instance of the adapter factory. + * + * + * @generated + */ + public PointerAnalysisAdapterFactory() { + if (modelPackage == null) { + modelPackage = PointerAnalysisPackage.eINSTANCE; + } + } + + /** + * Returns whether this factory is applicable for the type of the object. + * + * This implementation returns true if the object is either the model's package or is an instance object of the model. + * + * @return whether this factory is applicable for the type of the object. + * @generated + */ + public boolean isFactoryForType(Object object) { + if (object == modelPackage) { + return true; + } + if (object instanceof EObject) { + return ((EObject)object).eClass().getEPackage() == modelPackage; + } + return false; + } + + /** + * The switch the delegates to the createXXX methods. + * + * + * @generated + */ + protected PointerAnalysisSwitch modelSwitch = + new PointerAnalysisSwitch() { + public Object caseEPointer(EPointer object) { + return createEPointerAdapter(); + } + public Object caseEInstanceField(EInstanceField object) { + return createEInstanceFieldAdapter(); + } + public Object caseEArrayContents(EArrayContents object) { + return createEArrayContentsAdapter(); + } + public Object caseEStaticField(EStaticField object) { + return createEStaticFieldAdapter(); + } + public Object caseELocalPointer(ELocalPointer object) { + return createELocalPointerAdapter(); + } + public Object caseEReturnValuePointer(EReturnValuePointer object) { + return createEReturnValuePointerAdapter(); + } + public Object caseEInstance(EInstance object) { + return createEInstanceAdapter(); + } + public Object caseEJavaClassInstance(EJavaClassInstance object) { + return createEJavaClassInstanceAdapter(); + } + public Object caseEHeapGraph(EHeapGraph object) { + return createEHeapGraphAdapter(); + } + public Object caseEGraph(EGraph object) { + return createEGraphAdapter(); + } + public Object defaultCase(EObject object) { + return createEObjectAdapter(); + } + }; + + /** + * Creates an adapter for the target. + * + * + * @param target the object to adapt. + * @return the adapter for the target. + * @generated + */ + public Adapter createAdapter(Notifier target) { + return (Adapter)modelSwitch.doSwitch((EObject)target); + } + + + /** + * Creates a new adapter for an object of class '{@link com.ibm.wala.ecore.java.pointerAnalysis.EPointer EPointer}'. + * + * This default implementation returns null so that we can easily ignore cases; + * it's useful to ignore a case when inheritance will catch all the cases anyway. + * + * @return the new adapter. + * @see com.ibm.wala.ecore.java.pointerAnalysis.EPointer + * @generated + */ + public Adapter createEPointerAdapter() { + return null; + } + + /** + * Creates a new adapter for an object of class '{@link com.ibm.wala.ecore.java.pointerAnalysis.EInstanceField EInstance Field}'. + * + * This default implementation returns null so that we can easily ignore cases; + * it's useful to ignore a case when inheritance will catch all the cases anyway. + * + * @return the new adapter. + * @see com.ibm.wala.ecore.java.pointerAnalysis.EInstanceField + * @generated + */ + public Adapter createEInstanceFieldAdapter() { + return null; + } + + /** + * Creates a new adapter for an object of class '{@link com.ibm.wala.ecore.java.pointerAnalysis.EArrayContents EArray Contents}'. + * + * This default implementation returns null so that we can easily ignore cases; + * it's useful to ignore a case when inheritance will catch all the cases anyway. + * + * @return the new adapter. + * @see com.ibm.wala.ecore.java.pointerAnalysis.EArrayContents + * @generated + */ + public Adapter createEArrayContentsAdapter() { + return null; + } + + /** + * Creates a new adapter for an object of class '{@link com.ibm.wala.ecore.java.pointerAnalysis.EStaticField EStatic Field}'. + * + * This default implementation returns null so that we can easily ignore cases; + * it's useful to ignore a case when inheritance will catch all the cases anyway. + * + * @return the new adapter. + * @see com.ibm.wala.ecore.java.pointerAnalysis.EStaticField + * @generated + */ + public Adapter createEStaticFieldAdapter() { + return null; + } + + /** + * Creates a new adapter for an object of class '{@link com.ibm.wala.ecore.java.pointerAnalysis.ELocalPointer ELocal Pointer}'. + * + * This default implementation returns null so that we can easily ignore cases; + * it's useful to ignore a case when inheritance will catch all the cases anyway. + * + * @return the new adapter. + * @see com.ibm.wala.ecore.java.pointerAnalysis.ELocalPointer + * @generated + */ + public Adapter createELocalPointerAdapter() { + return null; + } + + /** + * Creates a new adapter for an object of class '{@link com.ibm.wala.ecore.java.pointerAnalysis.EReturnValuePointer EReturn Value Pointer}'. + * + * This default implementation returns null so that we can easily ignore cases; + * it's useful to ignore a case when inheritance will catch all the cases anyway. + * + * @return the new adapter. + * @see com.ibm.wala.ecore.java.pointerAnalysis.EReturnValuePointer + * @generated + */ + public Adapter createEReturnValuePointerAdapter() { + return null; + } + + /** + * Creates a new adapter for an object of class '{@link com.ibm.wala.ecore.java.pointerAnalysis.EInstance EInstance}'. + * + * This default implementation returns null so that we can easily ignore cases; + * it's useful to ignore a case when inheritance will catch all the cases anyway. + * + * @return the new adapter. + * @see com.ibm.wala.ecore.java.pointerAnalysis.EInstance + * @generated + */ + public Adapter createEInstanceAdapter() { + return null; + } + + /** + * Creates a new adapter for an object of class '{@link com.ibm.wala.ecore.java.pointerAnalysis.EJavaClassInstance EJava Class Instance}'. + * + * This default implementation returns null so that we can easily ignore cases; + * it's useful to ignore a case when inheritance will catch all the cases anyway. + * + * @return the new adapter. + * @see com.ibm.wala.ecore.java.pointerAnalysis.EJavaClassInstance + * @generated + */ + public Adapter createEJavaClassInstanceAdapter() { + return null; + } + + /** + * Creates a new adapter for an object of class '{@link com.ibm.wala.ecore.java.pointerAnalysis.EHeapGraph EHeap Graph}'. + * + * This default implementation returns null so that we can easily ignore cases; + * it's useful to ignore a case when inheritance will catch all the cases anyway. + * + * @return the new adapter. + * @see com.ibm.wala.ecore.java.pointerAnalysis.EHeapGraph + * @generated + */ + public Adapter createEHeapGraphAdapter() { + return null; + } + + /** + * Creates a new adapter for an object of class '{@link com.ibm.wala.ecore.graph.EGraph EGraph}'. + * + * This default implementation returns null so that we can easily ignore cases; + * it's useful to ignore a case when inheritance will catch all the cases anyway. + * + * @return the new adapter. + * @see com.ibm.wala.ecore.graph.EGraph + * @generated + */ + public Adapter createEGraphAdapter() { + return null; + } + + /** + * Creates a new adapter for the default case. + * + * This default implementation returns null. + * + * @return the new adapter. + * @generated + */ + public Adapter createEObjectAdapter() { + return null; + } + +} //PointerAnalysisAdapterFactory diff --git a/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/pointerAnalysis/util/PointerAnalysisSwitch.java b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/pointerAnalysis/util/PointerAnalysisSwitch.java new file mode 100644 index 000000000..b72675663 --- /dev/null +++ b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/pointerAnalysis/util/PointerAnalysisSwitch.java @@ -0,0 +1,322 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java.pointerAnalysis.util; + +import com.ibm.wala.ecore.graph.EGraph; + +import com.ibm.wala.ecore.java.pointerAnalysis.*; + +import java.util.List; + +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EObject; + +/** + * + * The Switch for the model's inheritance hierarchy. + * It supports the call {@link #doSwitch(EObject) doSwitch(object)} + * to invoke the caseXXX method for each class of the model, + * starting with the actual class of the object + * and proceeding up the inheritance hierarchy + * until a non-null result is returned, + * which is the result of the switch. + * + * @see com.ibm.wala.ecore.java.pointerAnalysis.PointerAnalysisPackage + * @generated + */ +public class PointerAnalysisSwitch { + /** + * The cached model package + * + * + * @generated + */ + protected static PointerAnalysisPackage modelPackage; + + /** + * Creates an instance of the switch. + * + * + * @generated + */ + public PointerAnalysisSwitch() { + if (modelPackage == null) { + modelPackage = PointerAnalysisPackage.eINSTANCE; + } + } + + /** + * Calls caseXXX for each class of the model until one returns a non null result; it yields that result. + * + * + * @return the first non-null result returned by a caseXXX call. + * @generated + */ + public Object doSwitch(EObject theEObject) { + return doSwitch(theEObject.eClass(), theEObject); + } + + /** + * Calls caseXXX for each class of the model until one returns a non null result; it yields that result. + * + * + * @return the first non-null result returned by a caseXXX call. + * @generated + */ + protected Object doSwitch(EClass theEClass, EObject theEObject) { + if (theEClass.eContainer() == modelPackage) { + return doSwitch(theEClass.getClassifierID(), theEObject); + } + else { + List eSuperTypes = theEClass.getESuperTypes(); + return + eSuperTypes.isEmpty() ? + defaultCase(theEObject) : + doSwitch((EClass)eSuperTypes.get(0), theEObject); + } + } + + /** + * Calls caseXXX for each class of the model until one returns a non null result; it yields that result. + * + * + * @return the first non-null result returned by a caseXXX call. + * @generated + */ + protected Object doSwitch(int classifierID, EObject theEObject) { + switch (classifierID) { + case PointerAnalysisPackage.EPOINTER: { + EPointer ePointer = (EPointer)theEObject; + Object result = caseEPointer(ePointer); + if (result == null) result = defaultCase(theEObject); + return result; + } + case PointerAnalysisPackage.EINSTANCE_FIELD: { + EInstanceField eInstanceField = (EInstanceField)theEObject; + Object result = caseEInstanceField(eInstanceField); + if (result == null) result = caseEPointer(eInstanceField); + if (result == null) result = defaultCase(theEObject); + return result; + } + case PointerAnalysisPackage.EARRAY_CONTENTS: { + EArrayContents eArrayContents = (EArrayContents)theEObject; + Object result = caseEArrayContents(eArrayContents); + if (result == null) result = caseEPointer(eArrayContents); + if (result == null) result = defaultCase(theEObject); + return result; + } + case PointerAnalysisPackage.ESTATIC_FIELD: { + EStaticField eStaticField = (EStaticField)theEObject; + Object result = caseEStaticField(eStaticField); + if (result == null) result = caseEPointer(eStaticField); + if (result == null) result = defaultCase(theEObject); + return result; + } + case PointerAnalysisPackage.ELOCAL_POINTER: { + ELocalPointer eLocalPointer = (ELocalPointer)theEObject; + Object result = caseELocalPointer(eLocalPointer); + if (result == null) result = caseEPointer(eLocalPointer); + if (result == null) result = defaultCase(theEObject); + return result; + } + case PointerAnalysisPackage.ERETURN_VALUE_POINTER: { + EReturnValuePointer eReturnValuePointer = (EReturnValuePointer)theEObject; + Object result = caseEReturnValuePointer(eReturnValuePointer); + if (result == null) result = caseEPointer(eReturnValuePointer); + if (result == null) result = defaultCase(theEObject); + return result; + } + case PointerAnalysisPackage.EINSTANCE: { + EInstance eInstance = (EInstance)theEObject; + Object result = caseEInstance(eInstance); + if (result == null) result = defaultCase(theEObject); + return result; + } + case PointerAnalysisPackage.EJAVA_CLASS_INSTANCE: { + EJavaClassInstance eJavaClassInstance = (EJavaClassInstance)theEObject; + Object result = caseEJavaClassInstance(eJavaClassInstance); + if (result == null) result = caseEInstance(eJavaClassInstance); + if (result == null) result = defaultCase(theEObject); + return result; + } + case PointerAnalysisPackage.EHEAP_GRAPH: { + EHeapGraph eHeapGraph = (EHeapGraph)theEObject; + Object result = caseEHeapGraph(eHeapGraph); + if (result == null) result = caseEGraph(eHeapGraph); + if (result == null) result = defaultCase(theEObject); + return result; + } + default: return defaultCase(theEObject); + } + } + + /** + * Returns the result of interpretting the object as an instance of 'EPointer'. + * + * This implementation returns null; + * returning a non-null result will terminate the switch. + * + * @param object the target of the switch. + * @return the result of interpretting the object as an instance of 'EPointer'. + * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject) + * @generated + */ + public Object caseEPointer(EPointer object) { + return null; + } + + /** + * Returns the result of interpretting the object as an instance of 'EInstance Field'. + * + * This implementation returns null; + * returning a non-null result will terminate the switch. + * + * @param object the target of the switch. + * @return the result of interpretting the object as an instance of 'EInstance Field'. + * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject) + * @generated + */ + public Object caseEInstanceField(EInstanceField object) { + return null; + } + + /** + * Returns the result of interpretting the object as an instance of 'EArray Contents'. + * + * This implementation returns null; + * returning a non-null result will terminate the switch. + * + * @param object the target of the switch. + * @return the result of interpretting the object as an instance of 'EArray Contents'. + * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject) + * @generated + */ + public Object caseEArrayContents(EArrayContents object) { + return null; + } + + /** + * Returns the result of interpretting the object as an instance of 'EStatic Field'. + * + * This implementation returns null; + * returning a non-null result will terminate the switch. + * + * @param object the target of the switch. + * @return the result of interpretting the object as an instance of 'EStatic Field'. + * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject) + * @generated + */ + public Object caseEStaticField(EStaticField object) { + return null; + } + + /** + * Returns the result of interpretting the object as an instance of 'ELocal Pointer'. + * + * This implementation returns null; + * returning a non-null result will terminate the switch. + * + * @param object the target of the switch. + * @return the result of interpretting the object as an instance of 'ELocal Pointer'. + * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject) + * @generated + */ + public Object caseELocalPointer(ELocalPointer object) { + return null; + } + + /** + * Returns the result of interpretting the object as an instance of 'EReturn Value Pointer'. + * + * This implementation returns null; + * returning a non-null result will terminate the switch. + * + * @param object the target of the switch. + * @return the result of interpretting the object as an instance of 'EReturn Value Pointer'. + * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject) + * @generated + */ + public Object caseEReturnValuePointer(EReturnValuePointer object) { + return null; + } + + /** + * Returns the result of interpretting the object as an instance of 'EInstance'. + * + * This implementation returns null; + * returning a non-null result will terminate the switch. + * + * @param object the target of the switch. + * @return the result of interpretting the object as an instance of 'EInstance'. + * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject) + * @generated + */ + public Object caseEInstance(EInstance object) { + return null; + } + + /** + * Returns the result of interpretting the object as an instance of 'EJava Class Instance'. + * + * This implementation returns null; + * returning a non-null result will terminate the switch. + * + * @param object the target of the switch. + * @return the result of interpretting the object as an instance of 'EJava Class Instance'. + * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject) + * @generated + */ + public Object caseEJavaClassInstance(EJavaClassInstance object) { + return null; + } + + /** + * Returns the result of interpretting the object as an instance of 'EHeap Graph'. + * + * This implementation returns null; + * returning a non-null result will terminate the switch. + * + * @param object the target of the switch. + * @return the result of interpretting the object as an instance of 'EHeap Graph'. + * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject) + * @generated + */ + public Object caseEHeapGraph(EHeapGraph object) { + return null; + } + + /** + * Returns the result of interpretting the object as an instance of 'EGraph'. + * + * This implementation returns null; + * returning a non-null result will terminate the switch. + * + * @param object the target of the switch. + * @return the result of interpretting the object as an instance of 'EGraph'. + * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject) + * @generated + */ + public Object caseEGraph(EGraph object) { + return null; + } + + /** + * Returns the result of interpretting the object as an instance of 'EObject'. + * + * This implementation returns null; + * returning a non-null result will terminate the switch, but this is the last case anyway. + * + * @param object the target of the switch. + * @return the result of interpretting the object as an instance of 'EObject'. + * @see #doSwitch(org.eclipse.emf.ecore.EObject) + * @generated + */ + public Object defaultCase(EObject object) { + return null; + } + +} //PointerAnalysisSwitch diff --git a/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/EBuiltInModule.java b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/EBuiltInModule.java new file mode 100644 index 000000000..dc4d4699a --- /dev/null +++ b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/EBuiltInModule.java @@ -0,0 +1,56 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java.scope; + + +/** + * + * A representation of the model object 'EBuilt In Module'. + * + * + *

                              + * The following features are supported: + *

                                + *
                              • {@link com.ibm.wala.ecore.java.scope.EBuiltInModule#getId Id}
                              • + *
                              + *

                              + * + * @see com.ibm.wala.ecore.java.scope.JavaScopePackage#getEBuiltInModule() + * @model + * @generated + */ +public interface EBuiltInModule extends EModule { + /** + * Returns the value of the 'Id' attribute. + * The literals are from the enumeration {@link com.ibm.wala.ecore.java.scope.EBuiltInResource}. + * + *

                              + * If the meaning of the 'Id' attribute isn't clear, + * there really should be more of a description here... + *

                              + * + * @return the value of the 'Id' attribute. + * @see com.ibm.wala.ecore.java.scope.EBuiltInResource + * @see #setId(EBuiltInResource) + * @see com.ibm.wala.ecore.java.scope.JavaScopePackage#getEBuiltInModule_Id() + * @model required="true" + * @generated + */ + EBuiltInResource getId(); + + /** + * Sets the value of the '{@link com.ibm.wala.ecore.java.scope.EBuiltInModule#getId Id}' attribute. + * + * + * @param value the new value of the 'Id' attribute. + * @see com.ibm.wala.ecore.java.scope.EBuiltInResource + * @see #getId() + * @generated + */ + void setId(EBuiltInResource value); + +} // EBuiltInModule \ No newline at end of file diff --git a/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/EBuiltInResource.java b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/EBuiltInResource.java new file mode 100644 index 000000000..a75ccc5f4 --- /dev/null +++ b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/EBuiltInResource.java @@ -0,0 +1,205 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java.scope; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import org.eclipse.emf.common.util.AbstractEnumerator; + +/** + * + * A representation of the literals of the enumeration 'EBuilt In Resource', + * and utility methods for working with them. + * + * @see com.ibm.wala.ecore.java.scope.JavaScopePackage#getEBuiltInResource() + * @model + * @generated + */ +public final class EBuiltInResource extends AbstractEnumerator { + /** + * The 'Default J2SE Libs' literal value. + * + *

                              + * If the meaning of 'Default J2SE Libs' literal object isn't clear, + * there really should be more of a description here... + *

                              + * + * @see #DEFAULT_J2SE_LIBS_LITERAL + * @model name="DefaultJ2SELibs" + * @generated + * @ordered + */ + public static final int DEFAULT_J2SE_LIBS = 0; + + /** + * The 'Default J2EE Libs' literal value. + * + *

                              + * If the meaning of 'Default J2EE Libs' literal object isn't clear, + * there really should be more of a description here... + *

                              + * + * @see #DEFAULT_J2EE_LIBS_LITERAL + * @model name="DefaultJ2EELibs" + * @generated + * @ordered + */ + public static final int DEFAULT_J2EE_LIBS = 1; + + /** + * The 'Primordial jar model' literal value. + * + *

                              + * If the meaning of 'Primordial jar model' literal object isn't clear, + * there really should be more of a description here... + *

                              + * + * @see #PRIMORDIAL_JAR_MODEL_LITERAL + * @model name="primordial_jar_model" + * @generated + * @ordered + */ + public static final int PRIMORDIAL_JAR_MODEL = 2; + + /** + * The 'Extension jar model' literal value. + * + *

                              + * If the meaning of 'Extension jar model' literal object isn't clear, + * there really should be more of a description here... + *

                              + * + * @see #EXTENSION_JAR_MODEL_LITERAL + * @model name="extension_jar_model" + * @generated + * @ordered + */ + public static final int EXTENSION_JAR_MODEL = 3; + + /** + * The 'Default J2SE Libs' literal object. + * + * + * @see #DEFAULT_J2SE_LIBS + * @generated + * @ordered + */ + public static final EBuiltInResource DEFAULT_J2SE_LIBS_LITERAL = new EBuiltInResource(DEFAULT_J2SE_LIBS, "DefaultJ2SELibs", "DefaultJ2SELibs"); + + /** + * The 'Default J2EE Libs' literal object. + * + * + * @see #DEFAULT_J2EE_LIBS + * @generated + * @ordered + */ + public static final EBuiltInResource DEFAULT_J2EE_LIBS_LITERAL = new EBuiltInResource(DEFAULT_J2EE_LIBS, "DefaultJ2EELibs", "DefaultJ2EELibs"); + + /** + * The 'Primordial jar model' literal object. + * + * + * @see #PRIMORDIAL_JAR_MODEL + * @generated + * @ordered + */ + public static final EBuiltInResource PRIMORDIAL_JAR_MODEL_LITERAL = new EBuiltInResource(PRIMORDIAL_JAR_MODEL, "primordial_jar_model", "primordial_jar_model"); + + /** + * The 'Extension jar model' literal object. + * + * + * @see #EXTENSION_JAR_MODEL + * @generated + * @ordered + */ + public static final EBuiltInResource EXTENSION_JAR_MODEL_LITERAL = new EBuiltInResource(EXTENSION_JAR_MODEL, "extension_jar_model", "extension_jar_model"); + + /** + * An array of all the 'EBuilt In Resource' enumerators. + * + * + * @generated + */ + private static final EBuiltInResource[] VALUES_ARRAY = + new EBuiltInResource[] { + DEFAULT_J2SE_LIBS_LITERAL, + DEFAULT_J2EE_LIBS_LITERAL, + PRIMORDIAL_JAR_MODEL_LITERAL, + EXTENSION_JAR_MODEL_LITERAL, + }; + + /** + * A public read-only list of all the 'EBuilt In Resource' enumerators. + * + * + * @generated + */ + public static final List VALUES = Collections.unmodifiableList(Arrays.asList(VALUES_ARRAY)); + + /** + * Returns the 'EBuilt In Resource' literal with the specified literal value. + * + * + * @generated + */ + public static EBuiltInResource get(String literal) { + for (int i = 0; i < VALUES_ARRAY.length; ++i) { + EBuiltInResource result = VALUES_ARRAY[i]; + if (result.toString().equals(literal)) { + return result; + } + } + return null; + } + + /** + * Returns the 'EBuilt In Resource' literal with the specified name. + * + * + * @generated + */ + public static EBuiltInResource getByName(String name) { + for (int i = 0; i < VALUES_ARRAY.length; ++i) { + EBuiltInResource result = VALUES_ARRAY[i]; + if (result.getName().equals(name)) { + return result; + } + } + return null; + } + + /** + * Returns the 'EBuilt In Resource' literal with the specified integer value. + * + * + * @generated + */ + public static EBuiltInResource get(int value) { + switch (value) { + case DEFAULT_J2SE_LIBS: return DEFAULT_J2SE_LIBS_LITERAL; + case DEFAULT_J2EE_LIBS: return DEFAULT_J2EE_LIBS_LITERAL; + case PRIMORDIAL_JAR_MODEL: return PRIMORDIAL_JAR_MODEL_LITERAL; + case EXTENSION_JAR_MODEL: return EXTENSION_JAR_MODEL_LITERAL; + } + return null; + } + + /** + * Only this class can construct instances. + * + * + * @generated + */ + private EBuiltInResource(int value, String name, String literal) { + super(value, name, literal); + } + +} //EBuiltInResource diff --git a/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/EClassFile.java b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/EClassFile.java new file mode 100644 index 000000000..dcaadd444 --- /dev/null +++ b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/EClassFile.java @@ -0,0 +1,21 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java.scope; + + +/** + * + * A representation of the model object 'EClass File'. + * + * + * + * @see com.ibm.wala.ecore.java.scope.JavaScopePackage#getEClassFile() + * @model + * @generated + */ +public interface EClassFile extends EFile { +} // EClassFile \ No newline at end of file diff --git a/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/EClassLoader.java b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/EClassLoader.java new file mode 100644 index 000000000..8f3ca010e --- /dev/null +++ b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/EClassLoader.java @@ -0,0 +1,73 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java.scope; + +import org.eclipse.emf.common.util.EList; + +import org.eclipse.emf.ecore.EObject; + +/** + * + * A representation of the model object 'EClass Loader'. + * + * + *

                              + * The following features are supported: + *

                                + *
                              • {@link com.ibm.wala.ecore.java.scope.EClassLoader#getModules Modules}
                              • + *
                              • {@link com.ibm.wala.ecore.java.scope.EClassLoader#getLoaderName Loader Name}
                              • + *
                              + *

                              + * + * @see com.ibm.wala.ecore.java.scope.JavaScopePackage#getEClassLoader() + * @model + * @generated + */ +public interface EClassLoader extends EObject { + /** + * Returns the value of the 'Modules' containment reference list. + * The list contents are of type {@link com.ibm.wala.ecore.java.scope.EModule}. + * + *

                              + * If the meaning of the 'Modules' containment reference list isn't clear, + * there really should be more of a description here... + *

                              + * + * @return the value of the 'Modules' containment reference list. + * @see com.ibm.wala.ecore.java.scope.JavaScopePackage#getEClassLoader_Modules() + * @model type="com.ibm.wala.ecore.java.scope.EModule" containment="true" required="true" + * @generated + */ + EList getModules(); + + /** + * Returns the value of the 'Loader Name' attribute. + * + *

                              + * If the meaning of the 'Loader Name' attribute isn't clear, + * there really should be more of a description here... + *

                              + * + * @return the value of the 'Loader Name' attribute. + * @see #setLoaderName(String) + * @see com.ibm.wala.ecore.java.scope.JavaScopePackage#getEClassLoader_LoaderName() + * @model + * @generated + */ + String getLoaderName(); + + /** + * Sets the value of the '{@link com.ibm.wala.ecore.java.scope.EClassLoader#getLoaderName Loader Name}' attribute. + * + * + * @param value the new value of the 'Loader Name' attribute. + * @see #getLoaderName() + * @generated + */ + void setLoaderName(String value); + +} // EClassLoader \ No newline at end of file diff --git a/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/EClasspath.java b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/EClasspath.java new file mode 100644 index 000000000..8dc93dc15 --- /dev/null +++ b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/EClasspath.java @@ -0,0 +1,54 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java.scope; + +import org.eclipse.emf.ecore.EObject; + +/** + * + * A representation of the model object 'EClasspath'. + * + * + *

                              + * The following features are supported: + *

                                + *
                              • {@link com.ibm.wala.ecore.java.scope.EClasspath#getString String}
                              • + *
                              + *

                              + * + * @see com.ibm.wala.ecore.java.scope.JavaScopePackage#getEClasspath() + * @model + * @generated + */ +public interface EClasspath extends EObject { + /** + * Returns the value of the 'String' attribute. + * + *

                              + * If the meaning of the 'String' attribute isn't clear, + * there really should be more of a description here... + *

                              + * + * @return the value of the 'String' attribute. + * @see #setString(String) + * @see com.ibm.wala.ecore.java.scope.JavaScopePackage#getEClasspath_String() + * @model required="true" + * @generated + */ + String getString(); + + /** + * Sets the value of the '{@link com.ibm.wala.ecore.java.scope.EClasspath#getString String}' attribute. + * + * + * @param value the new value of the 'String' attribute. + * @see #getString() + * @generated + */ + void setString(String value); + +} // EClasspath \ No newline at end of file diff --git a/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/EFile.java b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/EFile.java new file mode 100644 index 000000000..2c760b60b --- /dev/null +++ b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/EFile.java @@ -0,0 +1,53 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java.scope; + + +/** + * + * A representation of the model object 'EFile'. + * + * + *

                              + * The following features are supported: + *

                                + *
                              • {@link com.ibm.wala.ecore.java.scope.EFile#getUrl Url}
                              • + *
                              + *

                              + * + * @see com.ibm.wala.ecore.java.scope.JavaScopePackage#getEFile() + * @model + * @generated + */ +public interface EFile extends EModule { + /** + * Returns the value of the 'Url' attribute. + * + *

                              + * If the meaning of the 'Url' attribute isn't clear, + * there really should be more of a description here... + *

                              + * + * @return the value of the 'Url' attribute. + * @see #setUrl(String) + * @see com.ibm.wala.ecore.java.scope.JavaScopePackage#getEFile_Url() + * @model required="true" + * @generated + */ + String getUrl(); + + /** + * Sets the value of the '{@link com.ibm.wala.ecore.java.scope.EFile#getUrl Url}' attribute. + * + * + * @param value the new value of the 'Url' attribute. + * @see #getUrl() + * @generated + */ + void setUrl(String value); + +} // EFile \ No newline at end of file diff --git a/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/EJarFile.java b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/EJarFile.java new file mode 100644 index 000000000..22f8df932 --- /dev/null +++ b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/EJarFile.java @@ -0,0 +1,53 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java.scope; + + +/** + * + * A representation of the model object 'EJar File'. + * + * + *

                              + * The following features are supported: + *

                                + *
                              • {@link com.ibm.wala.ecore.java.scope.EJarFile#getUrl Url}
                              • + *
                              + *

                              + * + * @see com.ibm.wala.ecore.java.scope.JavaScopePackage#getEJarFile() + * @model + * @generated + */ +public interface EJarFile extends EModule { + /** + * Returns the value of the 'Url' attribute. + * + *

                              + * If the meaning of the 'Url' attribute isn't clear, + * there really should be more of a description here... + *

                              + * + * @return the value of the 'Url' attribute. + * @see #setUrl(String) + * @see com.ibm.wala.ecore.java.scope.JavaScopePackage#getEJarFile_Url() + * @model required="true" + * @generated + */ + String getUrl(); + + /** + * Sets the value of the '{@link com.ibm.wala.ecore.java.scope.EJarFile#getUrl Url}' attribute. + * + * + * @param value the new value of the 'Url' attribute. + * @see #getUrl() + * @generated + */ + void setUrl(String value); + +} // EJarFile \ No newline at end of file diff --git a/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/EJavaAnalysisScope.java b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/EJavaAnalysisScope.java new file mode 100644 index 000000000..3e27594f3 --- /dev/null +++ b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/EJavaAnalysisScope.java @@ -0,0 +1,73 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java.scope; + +import org.eclipse.emf.common.util.EList; + +import org.eclipse.emf.ecore.EObject; + +/** + * + * A representation of the model object 'EJava Analysis Scope'. + * + * + *

                              + * The following features are supported: + *

                                + *
                              • {@link com.ibm.wala.ecore.java.scope.EJavaAnalysisScope#getLoaders Loaders}
                              • + *
                              • {@link com.ibm.wala.ecore.java.scope.EJavaAnalysisScope#getExclusionFileName Exclusion File Name}
                              • + *
                              + *

                              + * + * @see com.ibm.wala.ecore.java.scope.JavaScopePackage#getEJavaAnalysisScope() + * @model + * @generated + */ +public interface EJavaAnalysisScope extends EObject { + /** + * Returns the value of the 'Loaders' containment reference list. + * The list contents are of type {@link com.ibm.wala.ecore.java.scope.EClassLoader}. + * + *

                              + * If the meaning of the 'Loaders' containment reference list isn't clear, + * there really should be more of a description here... + *

                              + * + * @return the value of the 'Loaders' containment reference list. + * @see com.ibm.wala.ecore.java.scope.JavaScopePackage#getEJavaAnalysisScope_Loaders() + * @model type="com.ibm.wala.ecore.java.scope.EClassLoader" containment="true" required="true" + * @generated + */ + EList getLoaders(); + + /** + * Returns the value of the 'Exclusion File Name' attribute. + * + *

                              + * If the meaning of the 'Exclusion File Name' attribute isn't clear, + * there really should be more of a description here... + *

                              + * + * @return the value of the 'Exclusion File Name' attribute. + * @see #setExclusionFileName(String) + * @see com.ibm.wala.ecore.java.scope.JavaScopePackage#getEJavaAnalysisScope_ExclusionFileName() + * @model + * @generated + */ + String getExclusionFileName(); + + /** + * Sets the value of the '{@link com.ibm.wala.ecore.java.scope.EJavaAnalysisScope#getExclusionFileName Exclusion File Name}' attribute. + * + * + * @param value the new value of the 'Exclusion File Name' attribute. + * @see #getExclusionFileName() + * @generated + */ + void setExclusionFileName(String value); + +} // EJavaAnalysisScope \ No newline at end of file diff --git a/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/EModule.java b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/EModule.java new file mode 100644 index 000000000..ea516f0ab --- /dev/null +++ b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/EModule.java @@ -0,0 +1,22 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java.scope; + +import org.eclipse.emf.ecore.EObject; + +/** + * + * A representation of the model object 'EModule'. + * + * + * + * @see com.ibm.wala.ecore.java.scope.JavaScopePackage#getEModule() + * @model interface="true" abstract="true" + * @generated + */ +public interface EModule extends EObject { +} // EModule \ No newline at end of file diff --git a/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/ESourceFile.java b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/ESourceFile.java new file mode 100644 index 000000000..dd0382503 --- /dev/null +++ b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/ESourceFile.java @@ -0,0 +1,21 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java.scope; + + +/** + * + * A representation of the model object 'ESource File'. + * + * + * + * @see com.ibm.wala.ecore.java.scope.JavaScopePackage#getESourceFile() + * @model + * @generated + */ +public interface ESourceFile extends EFile { +} // ESourceFile \ No newline at end of file diff --git a/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/EStandardClassLoader.java b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/EStandardClassLoader.java new file mode 100644 index 000000000..a8d9dcc33 --- /dev/null +++ b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/EStandardClassLoader.java @@ -0,0 +1,205 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java.scope; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import org.eclipse.emf.common.util.AbstractEnumerator; + +/** + * + * A representation of the literals of the enumeration 'EStandard Class Loader', + * and utility methods for working with them. + * + * @see com.ibm.wala.ecore.java.scope.JavaScopePackage#getEStandardClassLoader() + * @model + * @generated + */ +public final class EStandardClassLoader extends AbstractEnumerator { + /** + * The 'Primordial' literal value. + * + *

                              + * If the meaning of 'Primordial' literal object isn't clear, + * there really should be more of a description here... + *

                              + * + * @see #PRIMORDIAL_LITERAL + * @model name="Primordial" + * @generated + * @ordered + */ + public static final int PRIMORDIAL = 0; + + /** + * The 'Extension' literal value. + * + *

                              + * If the meaning of 'Extension' literal object isn't clear, + * there really should be more of a description here... + *

                              + * + * @see #EXTENSION_LITERAL + * @model name="Extension" + * @generated + * @ordered + */ + public static final int EXTENSION = 1; + + /** + * The 'Application' literal value. + * + *

                              + * If the meaning of 'Application' literal object isn't clear, + * there really should be more of a description here... + *

                              + * + * @see #APPLICATION_LITERAL + * @model name="Application" + * @generated + * @ordered + */ + public static final int APPLICATION = 2; + + /** + * The 'Synthetic' literal value. + * + *

                              + * If the meaning of 'Synthetic' literal object isn't clear, + * there really should be more of a description here... + *

                              + * + * @see #SYNTHETIC_LITERAL + * @model name="Synthetic" + * @generated + * @ordered + */ + public static final int SYNTHETIC = 4; + + /** + * The 'Primordial' literal object. + * + * + * @see #PRIMORDIAL + * @generated + * @ordered + */ + public static final EStandardClassLoader PRIMORDIAL_LITERAL = new EStandardClassLoader(PRIMORDIAL, "Primordial", "Primordial"); + + /** + * The 'Extension' literal object. + * + * + * @see #EXTENSION + * @generated + * @ordered + */ + public static final EStandardClassLoader EXTENSION_LITERAL = new EStandardClassLoader(EXTENSION, "Extension", "Extension"); + + /** + * The 'Application' literal object. + * + * + * @see #APPLICATION + * @generated + * @ordered + */ + public static final EStandardClassLoader APPLICATION_LITERAL = new EStandardClassLoader(APPLICATION, "Application", "Application"); + + /** + * The 'Synthetic' literal object. + * + * + * @see #SYNTHETIC + * @generated + * @ordered + */ + public static final EStandardClassLoader SYNTHETIC_LITERAL = new EStandardClassLoader(SYNTHETIC, "Synthetic", "Synthetic"); + + /** + * An array of all the 'EStandard Class Loader' enumerators. + * + * + * @generated + */ + private static final EStandardClassLoader[] VALUES_ARRAY = + new EStandardClassLoader[] { + PRIMORDIAL_LITERAL, + EXTENSION_LITERAL, + APPLICATION_LITERAL, + SYNTHETIC_LITERAL, + }; + + /** + * A public read-only list of all the 'EStandard Class Loader' enumerators. + * + * + * @generated + */ + public static final List VALUES = Collections.unmodifiableList(Arrays.asList(VALUES_ARRAY)); + + /** + * Returns the 'EStandard Class Loader' literal with the specified literal value. + * + * + * @generated + */ + public static EStandardClassLoader get(String literal) { + for (int i = 0; i < VALUES_ARRAY.length; ++i) { + EStandardClassLoader result = VALUES_ARRAY[i]; + if (result.toString().equals(literal)) { + return result; + } + } + return null; + } + + /** + * Returns the 'EStandard Class Loader' literal with the specified name. + * + * + * @generated + */ + public static EStandardClassLoader getByName(String name) { + for (int i = 0; i < VALUES_ARRAY.length; ++i) { + EStandardClassLoader result = VALUES_ARRAY[i]; + if (result.getName().equals(name)) { + return result; + } + } + return null; + } + + /** + * Returns the 'EStandard Class Loader' literal with the specified integer value. + * + * + * @generated + */ + public static EStandardClassLoader get(int value) { + switch (value) { + case PRIMORDIAL: return PRIMORDIAL_LITERAL; + case EXTENSION: return EXTENSION_LITERAL; + case APPLICATION: return APPLICATION_LITERAL; + case SYNTHETIC: return SYNTHETIC_LITERAL; + } + return null; + } + + /** + * Only this class can construct instances. + * + * + * @generated + */ + private EStandardClassLoader(int value, String name, String literal) { + super(value, name, literal); + } + +} //EStandardClassLoader diff --git a/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/JavaScopeFactory.java b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/JavaScopeFactory.java new file mode 100644 index 000000000..1e7461e9e --- /dev/null +++ b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/JavaScopeFactory.java @@ -0,0 +1,109 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java.scope; + +import org.eclipse.emf.ecore.EFactory; + +/** + * + * The Factory for the model. + * It provides a create method for each non-abstract class of the model. + * + * @see com.ibm.wala.ecore.java.scope.JavaScopePackage + * @generated + */ +public interface JavaScopeFactory extends EFactory { + /** + * The singleton instance of the factory. + * + * + * @generated + */ + JavaScopeFactory eINSTANCE = com.ibm.wala.ecore.java.scope.impl.JavaScopeFactoryImpl.init(); + + /** + * Returns a new object of class 'EJava Analysis Scope'. + * + * + * @return a new object of class 'EJava Analysis Scope'. + * @generated + */ + EJavaAnalysisScope createEJavaAnalysisScope(); + + /** + * Returns a new object of class 'EClass Loader'. + * + * + * @return a new object of class 'EClass Loader'. + * @generated + */ + EClassLoader createEClassLoader(); + + /** + * Returns a new object of class 'EBuilt In Module'. + * + * + * @return a new object of class 'EBuilt In Module'. + * @generated + */ + EBuiltInModule createEBuiltInModule(); + + /** + * Returns a new object of class 'EJar File'. + * + * + * @return a new object of class 'EJar File'. + * @generated + */ + EJarFile createEJarFile(); + + /** + * Returns a new object of class 'EFile'. + * + * + * @return a new object of class 'EFile'. + * @generated + */ + EFile createEFile(); + + /** + * Returns a new object of class 'EClass File'. + * + * + * @return a new object of class 'EClass File'. + * @generated + */ + EClassFile createEClassFile(); + + /** + * Returns a new object of class 'ESource File'. + * + * + * @return a new object of class 'ESource File'. + * @generated + */ + ESourceFile createESourceFile(); + + /** + * Returns a new object of class 'EClasspath'. + * + * + * @return a new object of class 'EClasspath'. + * @generated + */ + EClasspath createEClasspath(); + + /** + * Returns the package supported by this factory. + * + * + * @return the package supported by this factory. + * @generated + */ + JavaScopePackage getJavaScopePackage(); + +} //JavaScopeFactory diff --git a/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/JavaScopePackage.java b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/JavaScopePackage.java new file mode 100644 index 000000000..dc41814e4 --- /dev/null +++ b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/JavaScopePackage.java @@ -0,0 +1,741 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java.scope; + +import org.eclipse.emf.ecore.EAttribute; +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EEnum; +import org.eclipse.emf.ecore.EPackage; +import org.eclipse.emf.ecore.EReference; + +/** + * + * The Package for the model. + * It contains accessors for the meta objects to represent + *
                                + *
                              • each class,
                              • + *
                              • each feature of each class,
                              • + *
                              • each enum,
                              • + *
                              • and each data type
                              • + *
                              + * + * @see com.ibm.wala.ecore.java.scope.JavaScopeFactory + * @model kind="package" + * @generated + */ +public interface JavaScopePackage extends EPackage { + /** + * The package name. + * + * + * @generated + */ + String eNAME = "scope"; + + /** + * The package namespace URI. + * + * + * @generated + */ + String eNS_URI = "http:///com/ibm/wala/wala.ecore.java.scope"; + + /** + * The package namespace name. + * + * + * @generated + */ + String eNS_PREFIX = "com.ibm.wala.java.scope"; + + /** + * The singleton instance of the package. + * + * + * @generated + */ + JavaScopePackage eINSTANCE = com.ibm.wala.ecore.java.scope.impl.JavaScopePackageImpl.init(); + + /** + * The meta object id for the '{@link com.ibm.wala.ecore.java.scope.impl.EJavaAnalysisScopeImpl EJava Analysis Scope}' class. + * + * + * @see com.ibm.wala.ecore.java.scope.impl.EJavaAnalysisScopeImpl + * @see com.ibm.wala.ecore.java.scope.impl.JavaScopePackageImpl#getEJavaAnalysisScope() + * @generated + */ + int EJAVA_ANALYSIS_SCOPE = 0; + + /** + * The feature id for the 'Loaders' containment reference list. + * + * + * @generated + * @ordered + */ + int EJAVA_ANALYSIS_SCOPE__LOADERS = 0; + + /** + * The feature id for the 'Exclusion File Name' attribute. + * + * + * @generated + * @ordered + */ + int EJAVA_ANALYSIS_SCOPE__EXCLUSION_FILE_NAME = 1; + + /** + * The number of structural features of the 'EJava Analysis Scope' class. + * + * + * @generated + * @ordered + */ + int EJAVA_ANALYSIS_SCOPE_FEATURE_COUNT = 2; + + /** + * The meta object id for the '{@link com.ibm.wala.ecore.java.scope.impl.EClassLoaderImpl EClass Loader}' class. + * + * + * @see com.ibm.wala.ecore.java.scope.impl.EClassLoaderImpl + * @see com.ibm.wala.ecore.java.scope.impl.JavaScopePackageImpl#getEClassLoader() + * @generated + */ + int ECLASS_LOADER = 1; + + /** + * The feature id for the 'Modules' containment reference list. + * + * + * @generated + * @ordered + */ + int ECLASS_LOADER__MODULES = 0; + + /** + * The feature id for the 'Loader Name' attribute. + * + * + * @generated + * @ordered + */ + int ECLASS_LOADER__LOADER_NAME = 1; + + /** + * The number of structural features of the 'EClass Loader' class. + * + * + * @generated + * @ordered + */ + int ECLASS_LOADER_FEATURE_COUNT = 2; + + /** + * The meta object id for the '{@link com.ibm.wala.ecore.java.scope.EModule EModule}' class. + * + * + * @see com.ibm.wala.ecore.java.scope.EModule + * @see com.ibm.wala.ecore.java.scope.impl.JavaScopePackageImpl#getEModule() + * @generated + */ + int EMODULE = 2; + + /** + * The number of structural features of the 'EModule' class. + * + * + * @generated + * @ordered + */ + int EMODULE_FEATURE_COUNT = 0; + + /** + * The meta object id for the '{@link com.ibm.wala.ecore.java.scope.impl.EBuiltInModuleImpl EBuilt In Module}' class. + * + * + * @see com.ibm.wala.ecore.java.scope.impl.EBuiltInModuleImpl + * @see com.ibm.wala.ecore.java.scope.impl.JavaScopePackageImpl#getEBuiltInModule() + * @generated + */ + int EBUILT_IN_MODULE = 3; + + /** + * The feature id for the 'Id' attribute. + * + * + * @generated + * @ordered + */ + int EBUILT_IN_MODULE__ID = EMODULE_FEATURE_COUNT + 0; + + /** + * The number of structural features of the 'EBuilt In Module' class. + * + * + * @generated + * @ordered + */ + int EBUILT_IN_MODULE_FEATURE_COUNT = EMODULE_FEATURE_COUNT + 1; + + /** + * The meta object id for the '{@link com.ibm.wala.ecore.java.scope.impl.EJarFileImpl EJar File}' class. + * + * + * @see com.ibm.wala.ecore.java.scope.impl.EJarFileImpl + * @see com.ibm.wala.ecore.java.scope.impl.JavaScopePackageImpl#getEJarFile() + * @generated + */ + int EJAR_FILE = 4; + + /** + * The feature id for the 'Url' attribute. + * + * + * @generated + * @ordered + */ + int EJAR_FILE__URL = EMODULE_FEATURE_COUNT + 0; + + /** + * The number of structural features of the 'EJar File' class. + * + * + * @generated + * @ordered + */ + int EJAR_FILE_FEATURE_COUNT = EMODULE_FEATURE_COUNT + 1; + + /** + * The meta object id for the '{@link com.ibm.wala.ecore.java.scope.impl.EFileImpl EFile}' class. + * + * + * @see com.ibm.wala.ecore.java.scope.impl.EFileImpl + * @see com.ibm.wala.ecore.java.scope.impl.JavaScopePackageImpl#getEFile() + * @generated + */ + int EFILE = 5; + + /** + * The feature id for the 'Url' attribute. + * + * + * @generated + * @ordered + */ + int EFILE__URL = EMODULE_FEATURE_COUNT + 0; + + /** + * The number of structural features of the 'EFile' class. + * + * + * @generated + * @ordered + */ + int EFILE_FEATURE_COUNT = EMODULE_FEATURE_COUNT + 1; + + /** + * The meta object id for the '{@link com.ibm.wala.ecore.java.scope.impl.EClassFileImpl EClass File}' class. + * + * + * @see com.ibm.wala.ecore.java.scope.impl.EClassFileImpl + * @see com.ibm.wala.ecore.java.scope.impl.JavaScopePackageImpl#getEClassFile() + * @generated + */ + int ECLASS_FILE = 6; + + /** + * The feature id for the 'Url' attribute. + * + * + * @generated + * @ordered + */ + int ECLASS_FILE__URL = EFILE__URL; + + /** + * The number of structural features of the 'EClass File' class. + * + * + * @generated + * @ordered + */ + int ECLASS_FILE_FEATURE_COUNT = EFILE_FEATURE_COUNT + 0; + + /** + * The meta object id for the '{@link com.ibm.wala.ecore.java.scope.impl.ESourceFileImpl ESource File}' class. + * + * + * @see com.ibm.wala.ecore.java.scope.impl.ESourceFileImpl + * @see com.ibm.wala.ecore.java.scope.impl.JavaScopePackageImpl#getESourceFile() + * @generated + */ + int ESOURCE_FILE = 7; + + /** + * The feature id for the 'Url' attribute. + * + * + * @generated + * @ordered + */ + int ESOURCE_FILE__URL = EFILE__URL; + + /** + * The number of structural features of the 'ESource File' class. + * + * + * @generated + * @ordered + */ + int ESOURCE_FILE_FEATURE_COUNT = EFILE_FEATURE_COUNT + 0; + + /** + * The meta object id for the '{@link com.ibm.wala.ecore.java.scope.impl.EClasspathImpl EClasspath}' class. + * + * + * @see com.ibm.wala.ecore.java.scope.impl.EClasspathImpl + * @see com.ibm.wala.ecore.java.scope.impl.JavaScopePackageImpl#getEClasspath() + * @generated + */ + int ECLASSPATH = 8; + + /** + * The feature id for the 'String' attribute. + * + * + * @generated + * @ordered + */ + int ECLASSPATH__STRING = 0; + + /** + * The number of structural features of the 'EClasspath' class. + * + * + * @generated + * @ordered + */ + int ECLASSPATH_FEATURE_COUNT = 1; + + /** + * The meta object id for the '{@link com.ibm.wala.ecore.java.scope.EBuiltInResource EBuilt In Resource}' enum. + * + * + * @see com.ibm.wala.ecore.java.scope.EBuiltInResource + * @see com.ibm.wala.ecore.java.scope.impl.JavaScopePackageImpl#getEBuiltInResource() + * @generated + */ + int EBUILT_IN_RESOURCE = 9; + + /** + * The meta object id for the '{@link com.ibm.wala.ecore.java.scope.EStandardClassLoader EStandard Class Loader}' enum. + * + * + * @see com.ibm.wala.ecore.java.scope.EStandardClassLoader + * @see com.ibm.wala.ecore.java.scope.impl.JavaScopePackageImpl#getEStandardClassLoader() + * @generated + */ + int ESTANDARD_CLASS_LOADER = 10; + + + /** + * Returns the meta object for class '{@link com.ibm.wala.ecore.java.scope.EJavaAnalysisScope EJava Analysis Scope}'. + * + * + * @return the meta object for class 'EJava Analysis Scope'. + * @see com.ibm.wala.ecore.java.scope.EJavaAnalysisScope + * @generated + */ + EClass getEJavaAnalysisScope(); + + /** + * Returns the meta object for the containment reference list '{@link com.ibm.wala.ecore.java.scope.EJavaAnalysisScope#getLoaders Loaders}'. + * + * + * @return the meta object for the containment reference list 'Loaders'. + * @see com.ibm.wala.ecore.java.scope.EJavaAnalysisScope#getLoaders() + * @see #getEJavaAnalysisScope() + * @generated + */ + EReference getEJavaAnalysisScope_Loaders(); + + /** + * Returns the meta object for the attribute '{@link com.ibm.wala.ecore.java.scope.EJavaAnalysisScope#getExclusionFileName Exclusion File Name}'. + * + * + * @return the meta object for the attribute 'Exclusion File Name'. + * @see com.ibm.wala.ecore.java.scope.EJavaAnalysisScope#getExclusionFileName() + * @see #getEJavaAnalysisScope() + * @generated + */ + EAttribute getEJavaAnalysisScope_ExclusionFileName(); + + /** + * Returns the meta object for class '{@link com.ibm.wala.ecore.java.scope.EClassLoader EClass Loader}'. + * + * + * @return the meta object for class 'EClass Loader'. + * @see com.ibm.wala.ecore.java.scope.EClassLoader + * @generated + */ + EClass getEClassLoader(); + + /** + * Returns the meta object for the containment reference list '{@link com.ibm.wala.ecore.java.scope.EClassLoader#getModules Modules}'. + * + * + * @return the meta object for the containment reference list 'Modules'. + * @see com.ibm.wala.ecore.java.scope.EClassLoader#getModules() + * @see #getEClassLoader() + * @generated + */ + EReference getEClassLoader_Modules(); + + /** + * Returns the meta object for the attribute '{@link com.ibm.wala.ecore.java.scope.EClassLoader#getLoaderName Loader Name}'. + * + * + * @return the meta object for the attribute 'Loader Name'. + * @see com.ibm.wala.ecore.java.scope.EClassLoader#getLoaderName() + * @see #getEClassLoader() + * @generated + */ + EAttribute getEClassLoader_LoaderName(); + + /** + * Returns the meta object for class '{@link com.ibm.wala.ecore.java.scope.EModule EModule}'. + * + * + * @return the meta object for class 'EModule'. + * @see com.ibm.wala.ecore.java.scope.EModule + * @generated + */ + EClass getEModule(); + + /** + * Returns the meta object for class '{@link com.ibm.wala.ecore.java.scope.EBuiltInModule EBuilt In Module}'. + * + * + * @return the meta object for class 'EBuilt In Module'. + * @see com.ibm.wala.ecore.java.scope.EBuiltInModule + * @generated + */ + EClass getEBuiltInModule(); + + /** + * Returns the meta object for the attribute '{@link com.ibm.wala.ecore.java.scope.EBuiltInModule#getId Id}'. + * + * + * @return the meta object for the attribute 'Id'. + * @see com.ibm.wala.ecore.java.scope.EBuiltInModule#getId() + * @see #getEBuiltInModule() + * @generated + */ + EAttribute getEBuiltInModule_Id(); + + /** + * Returns the meta object for class '{@link com.ibm.wala.ecore.java.scope.EJarFile EJar File}'. + * + * + * @return the meta object for class 'EJar File'. + * @see com.ibm.wala.ecore.java.scope.EJarFile + * @generated + */ + EClass getEJarFile(); + + /** + * Returns the meta object for the attribute '{@link com.ibm.wala.ecore.java.scope.EJarFile#getUrl Url}'. + * + * + * @return the meta object for the attribute 'Url'. + * @see com.ibm.wala.ecore.java.scope.EJarFile#getUrl() + * @see #getEJarFile() + * @generated + */ + EAttribute getEJarFile_Url(); + + /** + * Returns the meta object for class '{@link com.ibm.wala.ecore.java.scope.EFile EFile}'. + * + * + * @return the meta object for class 'EFile'. + * @see com.ibm.wala.ecore.java.scope.EFile + * @generated + */ + EClass getEFile(); + + /** + * Returns the meta object for the attribute '{@link com.ibm.wala.ecore.java.scope.EFile#getUrl Url}'. + * + * + * @return the meta object for the attribute 'Url'. + * @see com.ibm.wala.ecore.java.scope.EFile#getUrl() + * @see #getEFile() + * @generated + */ + EAttribute getEFile_Url(); + + /** + * Returns the meta object for class '{@link com.ibm.wala.ecore.java.scope.EClassFile EClass File}'. + * + * + * @return the meta object for class 'EClass File'. + * @see com.ibm.wala.ecore.java.scope.EClassFile + * @generated + */ + EClass getEClassFile(); + + /** + * Returns the meta object for class '{@link com.ibm.wala.ecore.java.scope.ESourceFile ESource File}'. + * + * + * @return the meta object for class 'ESource File'. + * @see com.ibm.wala.ecore.java.scope.ESourceFile + * @generated + */ + EClass getESourceFile(); + + /** + * Returns the meta object for class '{@link com.ibm.wala.ecore.java.scope.EClasspath EClasspath}'. + * + * + * @return the meta object for class 'EClasspath'. + * @see com.ibm.wala.ecore.java.scope.EClasspath + * @generated + */ + EClass getEClasspath(); + + /** + * Returns the meta object for the attribute '{@link com.ibm.wala.ecore.java.scope.EClasspath#getString String}'. + * + * + * @return the meta object for the attribute 'String'. + * @see com.ibm.wala.ecore.java.scope.EClasspath#getString() + * @see #getEClasspath() + * @generated + */ + EAttribute getEClasspath_String(); + + /** + * Returns the meta object for enum '{@link com.ibm.wala.ecore.java.scope.EBuiltInResource EBuilt In Resource}'. + * + * + * @return the meta object for enum 'EBuilt In Resource'. + * @see com.ibm.wala.ecore.java.scope.EBuiltInResource + * @generated + */ + EEnum getEBuiltInResource(); + + /** + * Returns the meta object for enum '{@link com.ibm.wala.ecore.java.scope.EStandardClassLoader EStandard Class Loader}'. + * + * + * @return the meta object for enum 'EStandard Class Loader'. + * @see com.ibm.wala.ecore.java.scope.EStandardClassLoader + * @generated + */ + EEnum getEStandardClassLoader(); + + /** + * Returns the factory that creates the instances of the model. + * + * + * @return the factory that creates the instances of the model. + * @generated + */ + JavaScopeFactory getJavaScopeFactory(); + + /** + * + * Defines literals for the meta objects that represent + *
                                + *
                              • each class,
                              • + *
                              • each feature of each class,
                              • + *
                              • each enum,
                              • + *
                              • and each data type
                              • + *
                              + * + * @generated + */ + interface Literals { + /** + * The meta object literal for the '{@link com.ibm.wala.ecore.java.scope.impl.EJavaAnalysisScopeImpl EJava Analysis Scope}' class. + * + * + * @see com.ibm.wala.ecore.java.scope.impl.EJavaAnalysisScopeImpl + * @see com.ibm.wala.ecore.java.scope.impl.JavaScopePackageImpl#getEJavaAnalysisScope() + * @generated + */ + EClass EJAVA_ANALYSIS_SCOPE = eINSTANCE.getEJavaAnalysisScope(); + + /** + * The meta object literal for the 'Loaders' containment reference list feature. + * + * + * @generated + */ + EReference EJAVA_ANALYSIS_SCOPE__LOADERS = eINSTANCE.getEJavaAnalysisScope_Loaders(); + + /** + * The meta object literal for the 'Exclusion File Name' attribute feature. + * + * + * @generated + */ + EAttribute EJAVA_ANALYSIS_SCOPE__EXCLUSION_FILE_NAME = eINSTANCE.getEJavaAnalysisScope_ExclusionFileName(); + + /** + * The meta object literal for the '{@link com.ibm.wala.ecore.java.scope.impl.EClassLoaderImpl EClass Loader}' class. + * + * + * @see com.ibm.wala.ecore.java.scope.impl.EClassLoaderImpl + * @see com.ibm.wala.ecore.java.scope.impl.JavaScopePackageImpl#getEClassLoader() + * @generated + */ + EClass ECLASS_LOADER = eINSTANCE.getEClassLoader(); + + /** + * The meta object literal for the 'Modules' containment reference list feature. + * + * + * @generated + */ + EReference ECLASS_LOADER__MODULES = eINSTANCE.getEClassLoader_Modules(); + + /** + * The meta object literal for the 'Loader Name' attribute feature. + * + * + * @generated + */ + EAttribute ECLASS_LOADER__LOADER_NAME = eINSTANCE.getEClassLoader_LoaderName(); + + /** + * The meta object literal for the '{@link com.ibm.wala.ecore.java.scope.EModule EModule}' class. + * + * + * @see com.ibm.wala.ecore.java.scope.EModule + * @see com.ibm.wala.ecore.java.scope.impl.JavaScopePackageImpl#getEModule() + * @generated + */ + EClass EMODULE = eINSTANCE.getEModule(); + + /** + * The meta object literal for the '{@link com.ibm.wala.ecore.java.scope.impl.EBuiltInModuleImpl EBuilt In Module}' class. + * + * + * @see com.ibm.wala.ecore.java.scope.impl.EBuiltInModuleImpl + * @see com.ibm.wala.ecore.java.scope.impl.JavaScopePackageImpl#getEBuiltInModule() + * @generated + */ + EClass EBUILT_IN_MODULE = eINSTANCE.getEBuiltInModule(); + + /** + * The meta object literal for the 'Id' attribute feature. + * + * + * @generated + */ + EAttribute EBUILT_IN_MODULE__ID = eINSTANCE.getEBuiltInModule_Id(); + + /** + * The meta object literal for the '{@link com.ibm.wala.ecore.java.scope.impl.EJarFileImpl EJar File}' class. + * + * + * @see com.ibm.wala.ecore.java.scope.impl.EJarFileImpl + * @see com.ibm.wala.ecore.java.scope.impl.JavaScopePackageImpl#getEJarFile() + * @generated + */ + EClass EJAR_FILE = eINSTANCE.getEJarFile(); + + /** + * The meta object literal for the 'Url' attribute feature. + * + * + * @generated + */ + EAttribute EJAR_FILE__URL = eINSTANCE.getEJarFile_Url(); + + /** + * The meta object literal for the '{@link com.ibm.wala.ecore.java.scope.impl.EFileImpl EFile}' class. + * + * + * @see com.ibm.wala.ecore.java.scope.impl.EFileImpl + * @see com.ibm.wala.ecore.java.scope.impl.JavaScopePackageImpl#getEFile() + * @generated + */ + EClass EFILE = eINSTANCE.getEFile(); + + /** + * The meta object literal for the 'Url' attribute feature. + * + * + * @generated + */ + EAttribute EFILE__URL = eINSTANCE.getEFile_Url(); + + /** + * The meta object literal for the '{@link com.ibm.wala.ecore.java.scope.impl.EClassFileImpl EClass File}' class. + * + * + * @see com.ibm.wala.ecore.java.scope.impl.EClassFileImpl + * @see com.ibm.wala.ecore.java.scope.impl.JavaScopePackageImpl#getEClassFile() + * @generated + */ + EClass ECLASS_FILE = eINSTANCE.getEClassFile(); + + /** + * The meta object literal for the '{@link com.ibm.wala.ecore.java.scope.impl.ESourceFileImpl ESource File}' class. + * + * + * @see com.ibm.wala.ecore.java.scope.impl.ESourceFileImpl + * @see com.ibm.wala.ecore.java.scope.impl.JavaScopePackageImpl#getESourceFile() + * @generated + */ + EClass ESOURCE_FILE = eINSTANCE.getESourceFile(); + + /** + * The meta object literal for the '{@link com.ibm.wala.ecore.java.scope.impl.EClasspathImpl EClasspath}' class. + * + * + * @see com.ibm.wala.ecore.java.scope.impl.EClasspathImpl + * @see com.ibm.wala.ecore.java.scope.impl.JavaScopePackageImpl#getEClasspath() + * @generated + */ + EClass ECLASSPATH = eINSTANCE.getEClasspath(); + + /** + * The meta object literal for the 'String' attribute feature. + * + * + * @generated + */ + EAttribute ECLASSPATH__STRING = eINSTANCE.getEClasspath_String(); + + /** + * The meta object literal for the '{@link com.ibm.wala.ecore.java.scope.EBuiltInResource EBuilt In Resource}' enum. + * + * + * @see com.ibm.wala.ecore.java.scope.EBuiltInResource + * @see com.ibm.wala.ecore.java.scope.impl.JavaScopePackageImpl#getEBuiltInResource() + * @generated + */ + EEnum EBUILT_IN_RESOURCE = eINSTANCE.getEBuiltInResource(); + + /** + * The meta object literal for the '{@link com.ibm.wala.ecore.java.scope.EStandardClassLoader EStandard Class Loader}' enum. + * + * + * @see com.ibm.wala.ecore.java.scope.EStandardClassLoader + * @see com.ibm.wala.ecore.java.scope.impl.JavaScopePackageImpl#getEStandardClassLoader() + * @generated + */ + EEnum ESTANDARD_CLASS_LOADER = eINSTANCE.getEStandardClassLoader(); + + } + +} //JavaScopePackage diff --git a/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/impl/EBuiltInModuleImpl.java b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/impl/EBuiltInModuleImpl.java new file mode 100644 index 000000000..993ab1dfe --- /dev/null +++ b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/impl/EBuiltInModuleImpl.java @@ -0,0 +1,162 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java.scope.impl; + +import com.ibm.wala.ecore.java.scope.EBuiltInModule; +import com.ibm.wala.ecore.java.scope.EBuiltInResource; +import com.ibm.wala.ecore.java.scope.JavaScopePackage; + +import org.eclipse.emf.common.notify.Notification; + +import org.eclipse.emf.ecore.EClass; + +import org.eclipse.emf.ecore.impl.ENotificationImpl; +import org.eclipse.emf.ecore.impl.EObjectImpl; + +/** + * + * An implementation of the model object 'EBuilt In Module'. + * + *

                              + * The following features are implemented: + *

                                + *
                              • {@link com.ibm.wala.ecore.java.scope.impl.EBuiltInModuleImpl#getId Id}
                              • + *
                              + *

                              + * + * @generated + */ +public class EBuiltInModuleImpl extends EObjectImpl implements EBuiltInModule { + /** + * The default value of the '{@link #getId() Id}' attribute. + * + * + * @see #getId() + * @generated + * @ordered + */ + protected static final EBuiltInResource ID_EDEFAULT = EBuiltInResource.DEFAULT_J2SE_LIBS_LITERAL; + + /** + * The cached value of the '{@link #getId() Id}' attribute. + * + * + * @see #getId() + * @generated + * @ordered + */ + protected EBuiltInResource id = ID_EDEFAULT; + + /** + * + * + * @generated + */ + protected EBuiltInModuleImpl() { + super(); + } + + /** + * + * + * @generated + */ + protected EClass eStaticClass() { + return JavaScopePackage.Literals.EBUILT_IN_MODULE; + } + + /** + * + * + * @generated + */ + public EBuiltInResource getId() { + return id; + } + + /** + * + * + * @generated + */ + public void setId(EBuiltInResource newId) { + EBuiltInResource oldId = id; + id = newId == null ? ID_EDEFAULT : newId; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, JavaScopePackage.EBUILT_IN_MODULE__ID, oldId, id)); + } + + /** + * + * + * @generated + */ + public Object eGet(int featureID, boolean resolve, boolean coreType) { + switch (featureID) { + case JavaScopePackage.EBUILT_IN_MODULE__ID: + return getId(); + } + return super.eGet(featureID, resolve, coreType); + } + + /** + * + * + * @generated + */ + public void eSet(int featureID, Object newValue) { + switch (featureID) { + case JavaScopePackage.EBUILT_IN_MODULE__ID: + setId((EBuiltInResource)newValue); + return; + } + super.eSet(featureID, newValue); + } + + /** + * + * + * @generated + */ + public void eUnset(int featureID) { + switch (featureID) { + case JavaScopePackage.EBUILT_IN_MODULE__ID: + setId(ID_EDEFAULT); + return; + } + super.eUnset(featureID); + } + + /** + * + * + * @generated + */ + public boolean eIsSet(int featureID) { + switch (featureID) { + case JavaScopePackage.EBUILT_IN_MODULE__ID: + return id != ID_EDEFAULT; + } + return super.eIsSet(featureID); + } + + /** + * + * + * @generated + */ + public String toString() { + if (eIsProxy()) return super.toString(); + + StringBuffer result = new StringBuffer(super.toString()); + result.append(" (id: "); + result.append(id); + result.append(')'); + return result.toString(); + } + +} //EBuiltInModuleImpl \ No newline at end of file diff --git a/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/impl/EClassFileImpl.java b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/impl/EClassFileImpl.java new file mode 100644 index 000000000..686a024af --- /dev/null +++ b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/impl/EClassFileImpl.java @@ -0,0 +1,42 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java.scope.impl; + +import com.ibm.wala.ecore.java.scope.EClassFile; +import com.ibm.wala.ecore.java.scope.JavaScopePackage; + +import org.eclipse.emf.ecore.EClass; + +/** + * + * An implementation of the model object 'EClass File'. + * + *

                              + *

                              + * + * @generated + */ +public class EClassFileImpl extends EFileImpl implements EClassFile { + /** + * + * + * @generated + */ + protected EClassFileImpl() { + super(); + } + + /** + * + * + * @generated + */ + protected EClass eStaticClass() { + return JavaScopePackage.Literals.ECLASS_FILE; + } + +} //EClassFileImpl \ No newline at end of file diff --git a/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/impl/EClassLoaderImpl.java b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/impl/EClassLoaderImpl.java new file mode 100644 index 000000000..8557f8320 --- /dev/null +++ b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/impl/EClassLoaderImpl.java @@ -0,0 +1,218 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java.scope.impl; + +import com.ibm.wala.ecore.java.scope.EClassLoader; +import com.ibm.wala.ecore.java.scope.EModule; +import com.ibm.wala.ecore.java.scope.JavaScopePackage; + +import java.util.Collection; + +import org.eclipse.emf.common.notify.Notification; +import org.eclipse.emf.common.notify.NotificationChain; + +import org.eclipse.emf.common.util.EList; + +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.InternalEObject; + +import org.eclipse.emf.ecore.impl.ENotificationImpl; +import org.eclipse.emf.ecore.impl.EObjectImpl; + +import org.eclipse.emf.ecore.util.EObjectContainmentEList; +import org.eclipse.emf.ecore.util.InternalEList; + +/** + * + * An implementation of the model object 'EClass Loader'. + * + *

                              + * The following features are implemented: + *

                                + *
                              • {@link com.ibm.wala.ecore.java.scope.impl.EClassLoaderImpl#getModules Modules}
                              • + *
                              • {@link com.ibm.wala.ecore.java.scope.impl.EClassLoaderImpl#getLoaderName Loader Name}
                              • + *
                              + *

                              + * + * @generated + */ +public class EClassLoaderImpl extends EObjectImpl implements EClassLoader { + /** + * The cached value of the '{@link #getModules() Modules}' containment reference list. + * + * + * @see #getModules() + * @generated + * @ordered + */ + protected EList modules = null; + + /** + * The default value of the '{@link #getLoaderName() Loader Name}' attribute. + * + * + * @see #getLoaderName() + * @generated + * @ordered + */ + protected static final String LOADER_NAME_EDEFAULT = null; + + /** + * The cached value of the '{@link #getLoaderName() Loader Name}' attribute. + * + * + * @see #getLoaderName() + * @generated + * @ordered + */ + protected String loaderName = LOADER_NAME_EDEFAULT; + + /** + * + * + * @generated + */ + protected EClassLoaderImpl() { + super(); + } + + /** + * + * + * @generated + */ + protected EClass eStaticClass() { + return JavaScopePackage.Literals.ECLASS_LOADER; + } + + /** + * + * + * @generated + */ + public EList getModules() { + if (modules == null) { + modules = new EObjectContainmentEList(EModule.class, this, JavaScopePackage.ECLASS_LOADER__MODULES); + } + return modules; + } + + /** + * + * + * @generated + */ + public String getLoaderName() { + return loaderName; + } + + /** + * + * + * @generated + */ + public void setLoaderName(String newLoaderName) { + String oldLoaderName = loaderName; + loaderName = newLoaderName; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, JavaScopePackage.ECLASS_LOADER__LOADER_NAME, oldLoaderName, loaderName)); + } + + /** + * + * + * @generated + */ + public NotificationChain eInverseRemove(InternalEObject otherEnd, int featureID, NotificationChain msgs) { + switch (featureID) { + case JavaScopePackage.ECLASS_LOADER__MODULES: + return ((InternalEList)getModules()).basicRemove(otherEnd, msgs); + } + return super.eInverseRemove(otherEnd, featureID, msgs); + } + + /** + * + * + * @generated + */ + public Object eGet(int featureID, boolean resolve, boolean coreType) { + switch (featureID) { + case JavaScopePackage.ECLASS_LOADER__MODULES: + return getModules(); + case JavaScopePackage.ECLASS_LOADER__LOADER_NAME: + return getLoaderName(); + } + return super.eGet(featureID, resolve, coreType); + } + + /** + * + * + * @generated + */ + public void eSet(int featureID, Object newValue) { + switch (featureID) { + case JavaScopePackage.ECLASS_LOADER__MODULES: + getModules().clear(); + getModules().addAll((Collection)newValue); + return; + case JavaScopePackage.ECLASS_LOADER__LOADER_NAME: + setLoaderName((String)newValue); + return; + } + super.eSet(featureID, newValue); + } + + /** + * + * + * @generated + */ + public void eUnset(int featureID) { + switch (featureID) { + case JavaScopePackage.ECLASS_LOADER__MODULES: + getModules().clear(); + return; + case JavaScopePackage.ECLASS_LOADER__LOADER_NAME: + setLoaderName(LOADER_NAME_EDEFAULT); + return; + } + super.eUnset(featureID); + } + + /** + * + * + * @generated + */ + public boolean eIsSet(int featureID) { + switch (featureID) { + case JavaScopePackage.ECLASS_LOADER__MODULES: + return modules != null && !modules.isEmpty(); + case JavaScopePackage.ECLASS_LOADER__LOADER_NAME: + return LOADER_NAME_EDEFAULT == null ? loaderName != null : !LOADER_NAME_EDEFAULT.equals(loaderName); + } + return super.eIsSet(featureID); + } + + /** + * + * + * @generated + */ + public String toString() { + if (eIsProxy()) return super.toString(); + + StringBuffer result = new StringBuffer(super.toString()); + result.append(" (loaderName: "); + result.append(loaderName); + result.append(')'); + return result.toString(); + } + +} //EClassLoaderImpl \ No newline at end of file diff --git a/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/impl/EClasspathImpl.java b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/impl/EClasspathImpl.java new file mode 100644 index 000000000..b2f0e812b --- /dev/null +++ b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/impl/EClasspathImpl.java @@ -0,0 +1,161 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java.scope.impl; + +import com.ibm.wala.ecore.java.scope.EClasspath; +import com.ibm.wala.ecore.java.scope.JavaScopePackage; + +import org.eclipse.emf.common.notify.Notification; + +import org.eclipse.emf.ecore.EClass; + +import org.eclipse.emf.ecore.impl.ENotificationImpl; +import org.eclipse.emf.ecore.impl.EObjectImpl; + +/** + * + * An implementation of the model object 'EClasspath'. + * + *

                              + * The following features are implemented: + *

                                + *
                              • {@link com.ibm.wala.ecore.java.scope.impl.EClasspathImpl#getString String}
                              • + *
                              + *

                              + * + * @generated + */ +public class EClasspathImpl extends EObjectImpl implements EClasspath { + /** + * The default value of the '{@link #getString() String}' attribute. + * + * + * @see #getString() + * @generated + * @ordered + */ + protected static final String STRING_EDEFAULT = null; + + /** + * The cached value of the '{@link #getString() String}' attribute. + * + * + * @see #getString() + * @generated + * @ordered + */ + protected String string = STRING_EDEFAULT; + + /** + * + * + * @generated + */ + protected EClasspathImpl() { + super(); + } + + /** + * + * + * @generated + */ + protected EClass eStaticClass() { + return JavaScopePackage.Literals.ECLASSPATH; + } + + /** + * + * + * @generated + */ + public String getString() { + return string; + } + + /** + * + * + * @generated + */ + public void setString(String newString) { + String oldString = string; + string = newString; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, JavaScopePackage.ECLASSPATH__STRING, oldString, string)); + } + + /** + * + * + * @generated + */ + public Object eGet(int featureID, boolean resolve, boolean coreType) { + switch (featureID) { + case JavaScopePackage.ECLASSPATH__STRING: + return getString(); + } + return super.eGet(featureID, resolve, coreType); + } + + /** + * + * + * @generated + */ + public void eSet(int featureID, Object newValue) { + switch (featureID) { + case JavaScopePackage.ECLASSPATH__STRING: + setString((String)newValue); + return; + } + super.eSet(featureID, newValue); + } + + /** + * + * + * @generated + */ + public void eUnset(int featureID) { + switch (featureID) { + case JavaScopePackage.ECLASSPATH__STRING: + setString(STRING_EDEFAULT); + return; + } + super.eUnset(featureID); + } + + /** + * + * + * @generated + */ + public boolean eIsSet(int featureID) { + switch (featureID) { + case JavaScopePackage.ECLASSPATH__STRING: + return STRING_EDEFAULT == null ? string != null : !STRING_EDEFAULT.equals(string); + } + return super.eIsSet(featureID); + } + + /** + * + * + * @generated + */ + public String toString() { + if (eIsProxy()) return super.toString(); + + StringBuffer result = new StringBuffer(super.toString()); + result.append(" (string: "); + result.append(string); + result.append(')'); + return result.toString(); + } + +} //EClasspathImpl \ No newline at end of file diff --git a/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/impl/EFileImpl.java b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/impl/EFileImpl.java new file mode 100644 index 000000000..e83296b1f --- /dev/null +++ b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/impl/EFileImpl.java @@ -0,0 +1,161 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java.scope.impl; + +import com.ibm.wala.ecore.java.scope.EFile; +import com.ibm.wala.ecore.java.scope.JavaScopePackage; + +import org.eclipse.emf.common.notify.Notification; + +import org.eclipse.emf.ecore.EClass; + +import org.eclipse.emf.ecore.impl.ENotificationImpl; +import org.eclipse.emf.ecore.impl.EObjectImpl; + +/** + * + * An implementation of the model object 'EFile'. + * + *

                              + * The following features are implemented: + *

                                + *
                              • {@link com.ibm.wala.ecore.java.scope.impl.EFileImpl#getUrl Url}
                              • + *
                              + *

                              + * + * @generated + */ +public class EFileImpl extends EObjectImpl implements EFile { + /** + * The default value of the '{@link #getUrl() Url}' attribute. + * + * + * @see #getUrl() + * @generated + * @ordered + */ + protected static final String URL_EDEFAULT = null; + + /** + * The cached value of the '{@link #getUrl() Url}' attribute. + * + * + * @see #getUrl() + * @generated + * @ordered + */ + protected String url = URL_EDEFAULT; + + /** + * + * + * @generated + */ + protected EFileImpl() { + super(); + } + + /** + * + * + * @generated + */ + protected EClass eStaticClass() { + return JavaScopePackage.Literals.EFILE; + } + + /** + * + * + * @generated + */ + public String getUrl() { + return url; + } + + /** + * + * + * @generated + */ + public void setUrl(String newUrl) { + String oldUrl = url; + url = newUrl; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, JavaScopePackage.EFILE__URL, oldUrl, url)); + } + + /** + * + * + * @generated + */ + public Object eGet(int featureID, boolean resolve, boolean coreType) { + switch (featureID) { + case JavaScopePackage.EFILE__URL: + return getUrl(); + } + return super.eGet(featureID, resolve, coreType); + } + + /** + * + * + * @generated + */ + public void eSet(int featureID, Object newValue) { + switch (featureID) { + case JavaScopePackage.EFILE__URL: + setUrl((String)newValue); + return; + } + super.eSet(featureID, newValue); + } + + /** + * + * + * @generated + */ + public void eUnset(int featureID) { + switch (featureID) { + case JavaScopePackage.EFILE__URL: + setUrl(URL_EDEFAULT); + return; + } + super.eUnset(featureID); + } + + /** + * + * + * @generated + */ + public boolean eIsSet(int featureID) { + switch (featureID) { + case JavaScopePackage.EFILE__URL: + return URL_EDEFAULT == null ? url != null : !URL_EDEFAULT.equals(url); + } + return super.eIsSet(featureID); + } + + /** + * + * + * @generated + */ + public String toString() { + if (eIsProxy()) return super.toString(); + + StringBuffer result = new StringBuffer(super.toString()); + result.append(" (url: "); + result.append(url); + result.append(')'); + return result.toString(); + } + +} //EFileImpl \ No newline at end of file diff --git a/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/impl/EJarFileImpl.java b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/impl/EJarFileImpl.java new file mode 100644 index 000000000..b15d5f695 --- /dev/null +++ b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/impl/EJarFileImpl.java @@ -0,0 +1,161 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java.scope.impl; + +import com.ibm.wala.ecore.java.scope.EJarFile; +import com.ibm.wala.ecore.java.scope.JavaScopePackage; + +import org.eclipse.emf.common.notify.Notification; + +import org.eclipse.emf.ecore.EClass; + +import org.eclipse.emf.ecore.impl.ENotificationImpl; +import org.eclipse.emf.ecore.impl.EObjectImpl; + +/** + * + * An implementation of the model object 'EJar File'. + * + *

                              + * The following features are implemented: + *

                                + *
                              • {@link com.ibm.wala.ecore.java.scope.impl.EJarFileImpl#getUrl Url}
                              • + *
                              + *

                              + * + * @generated + */ +public class EJarFileImpl extends EObjectImpl implements EJarFile { + /** + * The default value of the '{@link #getUrl() Url}' attribute. + * + * + * @see #getUrl() + * @generated + * @ordered + */ + protected static final String URL_EDEFAULT = null; + + /** + * The cached value of the '{@link #getUrl() Url}' attribute. + * + * + * @see #getUrl() + * @generated + * @ordered + */ + protected String url = URL_EDEFAULT; + + /** + * + * + * @generated + */ + protected EJarFileImpl() { + super(); + } + + /** + * + * + * @generated + */ + protected EClass eStaticClass() { + return JavaScopePackage.Literals.EJAR_FILE; + } + + /** + * + * + * @generated + */ + public String getUrl() { + return url; + } + + /** + * + * + * @generated + */ + public void setUrl(String newUrl) { + String oldUrl = url; + url = newUrl; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, JavaScopePackage.EJAR_FILE__URL, oldUrl, url)); + } + + /** + * + * + * @generated + */ + public Object eGet(int featureID, boolean resolve, boolean coreType) { + switch (featureID) { + case JavaScopePackage.EJAR_FILE__URL: + return getUrl(); + } + return super.eGet(featureID, resolve, coreType); + } + + /** + * + * + * @generated + */ + public void eSet(int featureID, Object newValue) { + switch (featureID) { + case JavaScopePackage.EJAR_FILE__URL: + setUrl((String)newValue); + return; + } + super.eSet(featureID, newValue); + } + + /** + * + * + * @generated + */ + public void eUnset(int featureID) { + switch (featureID) { + case JavaScopePackage.EJAR_FILE__URL: + setUrl(URL_EDEFAULT); + return; + } + super.eUnset(featureID); + } + + /** + * + * + * @generated + */ + public boolean eIsSet(int featureID) { + switch (featureID) { + case JavaScopePackage.EJAR_FILE__URL: + return URL_EDEFAULT == null ? url != null : !URL_EDEFAULT.equals(url); + } + return super.eIsSet(featureID); + } + + /** + * + * + * @generated + */ + public String toString() { + if (eIsProxy()) return super.toString(); + + StringBuffer result = new StringBuffer(super.toString()); + result.append(" (url: "); + result.append(url); + result.append(')'); + return result.toString(); + } + +} //EJarFileImpl \ No newline at end of file diff --git a/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/impl/EJavaAnalysisScopeImpl.java b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/impl/EJavaAnalysisScopeImpl.java new file mode 100644 index 000000000..c0c7dfb68 --- /dev/null +++ b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/impl/EJavaAnalysisScopeImpl.java @@ -0,0 +1,218 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java.scope.impl; + +import com.ibm.wala.ecore.java.scope.EClassLoader; +import com.ibm.wala.ecore.java.scope.EJavaAnalysisScope; +import com.ibm.wala.ecore.java.scope.JavaScopePackage; + +import java.util.Collection; + +import org.eclipse.emf.common.notify.Notification; +import org.eclipse.emf.common.notify.NotificationChain; + +import org.eclipse.emf.common.util.EList; + +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.InternalEObject; + +import org.eclipse.emf.ecore.impl.ENotificationImpl; +import org.eclipse.emf.ecore.impl.EObjectImpl; + +import org.eclipse.emf.ecore.util.EObjectContainmentEList; +import org.eclipse.emf.ecore.util.InternalEList; + +/** + * + * An implementation of the model object 'EJava Analysis Scope'. + * + *

                              + * The following features are implemented: + *

                                + *
                              • {@link com.ibm.wala.ecore.java.scope.impl.EJavaAnalysisScopeImpl#getLoaders Loaders}
                              • + *
                              • {@link com.ibm.wala.ecore.java.scope.impl.EJavaAnalysisScopeImpl#getExclusionFileName Exclusion File Name}
                              • + *
                              + *

                              + * + * @generated + */ +public class EJavaAnalysisScopeImpl extends EObjectImpl implements EJavaAnalysisScope { + /** + * The cached value of the '{@link #getLoaders() Loaders}' containment reference list. + * + * + * @see #getLoaders() + * @generated + * @ordered + */ + protected EList loaders = null; + + /** + * The default value of the '{@link #getExclusionFileName() Exclusion File Name}' attribute. + * + * + * @see #getExclusionFileName() + * @generated + * @ordered + */ + protected static final String EXCLUSION_FILE_NAME_EDEFAULT = null; + + /** + * The cached value of the '{@link #getExclusionFileName() Exclusion File Name}' attribute. + * + * + * @see #getExclusionFileName() + * @generated + * @ordered + */ + protected String exclusionFileName = EXCLUSION_FILE_NAME_EDEFAULT; + + /** + * + * + * @generated + */ + protected EJavaAnalysisScopeImpl() { + super(); + } + + /** + * + * + * @generated + */ + protected EClass eStaticClass() { + return JavaScopePackage.Literals.EJAVA_ANALYSIS_SCOPE; + } + + /** + * + * + * @generated + */ + public EList getLoaders() { + if (loaders == null) { + loaders = new EObjectContainmentEList(EClassLoader.class, this, JavaScopePackage.EJAVA_ANALYSIS_SCOPE__LOADERS); + } + return loaders; + } + + /** + * + * + * @generated + */ + public String getExclusionFileName() { + return exclusionFileName; + } + + /** + * + * + * @generated + */ + public void setExclusionFileName(String newExclusionFileName) { + String oldExclusionFileName = exclusionFileName; + exclusionFileName = newExclusionFileName; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, JavaScopePackage.EJAVA_ANALYSIS_SCOPE__EXCLUSION_FILE_NAME, oldExclusionFileName, exclusionFileName)); + } + + /** + * + * + * @generated + */ + public NotificationChain eInverseRemove(InternalEObject otherEnd, int featureID, NotificationChain msgs) { + switch (featureID) { + case JavaScopePackage.EJAVA_ANALYSIS_SCOPE__LOADERS: + return ((InternalEList)getLoaders()).basicRemove(otherEnd, msgs); + } + return super.eInverseRemove(otherEnd, featureID, msgs); + } + + /** + * + * + * @generated + */ + public Object eGet(int featureID, boolean resolve, boolean coreType) { + switch (featureID) { + case JavaScopePackage.EJAVA_ANALYSIS_SCOPE__LOADERS: + return getLoaders(); + case JavaScopePackage.EJAVA_ANALYSIS_SCOPE__EXCLUSION_FILE_NAME: + return getExclusionFileName(); + } + return super.eGet(featureID, resolve, coreType); + } + + /** + * + * + * @generated + */ + public void eSet(int featureID, Object newValue) { + switch (featureID) { + case JavaScopePackage.EJAVA_ANALYSIS_SCOPE__LOADERS: + getLoaders().clear(); + getLoaders().addAll((Collection)newValue); + return; + case JavaScopePackage.EJAVA_ANALYSIS_SCOPE__EXCLUSION_FILE_NAME: + setExclusionFileName((String)newValue); + return; + } + super.eSet(featureID, newValue); + } + + /** + * + * + * @generated + */ + public void eUnset(int featureID) { + switch (featureID) { + case JavaScopePackage.EJAVA_ANALYSIS_SCOPE__LOADERS: + getLoaders().clear(); + return; + case JavaScopePackage.EJAVA_ANALYSIS_SCOPE__EXCLUSION_FILE_NAME: + setExclusionFileName(EXCLUSION_FILE_NAME_EDEFAULT); + return; + } + super.eUnset(featureID); + } + + /** + * + * + * @generated + */ + public boolean eIsSet(int featureID) { + switch (featureID) { + case JavaScopePackage.EJAVA_ANALYSIS_SCOPE__LOADERS: + return loaders != null && !loaders.isEmpty(); + case JavaScopePackage.EJAVA_ANALYSIS_SCOPE__EXCLUSION_FILE_NAME: + return EXCLUSION_FILE_NAME_EDEFAULT == null ? exclusionFileName != null : !EXCLUSION_FILE_NAME_EDEFAULT.equals(exclusionFileName); + } + return super.eIsSet(featureID); + } + + /** + * + * + * @generated + */ + public String toString() { + if (eIsProxy()) return super.toString(); + + StringBuffer result = new StringBuffer(super.toString()); + result.append(" (exclusionFileName: "); + result.append(exclusionFileName); + result.append(')'); + return result.toString(); + } + +} //EJavaAnalysisScopeImpl \ No newline at end of file diff --git a/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/impl/ESourceFileImpl.java b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/impl/ESourceFileImpl.java new file mode 100644 index 000000000..395f4b601 --- /dev/null +++ b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/impl/ESourceFileImpl.java @@ -0,0 +1,42 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java.scope.impl; + +import org.eclipse.emf.ecore.EClass; + +import com.ibm.wala.ecore.java.scope.ESourceFile; +import com.ibm.wala.ecore.java.scope.JavaScopePackage; + +/** + * + * An implementation of the model object 'ESource File'. + * + *

                              + *

                              + * + * @generated + */ +public class ESourceFileImpl extends EFileImpl implements ESourceFile { + /** + * + * + * @generated + */ + protected ESourceFileImpl() { + super(); + } + + /** + * + * + * @generated + */ + protected EClass eStaticClass() { + return JavaScopePackage.Literals.ESOURCE_FILE; + } + +} //ESourceFileImpl \ No newline at end of file diff --git a/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/impl/JavaScopeFactoryImpl.java b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/impl/JavaScopeFactoryImpl.java new file mode 100644 index 000000000..b0252f27d --- /dev/null +++ b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/impl/JavaScopeFactoryImpl.java @@ -0,0 +1,247 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java.scope.impl; + +import com.ibm.wala.ecore.java.scope.*; + +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EDataType; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EPackage; + +import org.eclipse.emf.ecore.impl.EFactoryImpl; + +import org.eclipse.emf.ecore.plugin.EcorePlugin; + +/** + * + * An implementation of the model Factory. + * + * @generated + */ +public class JavaScopeFactoryImpl extends EFactoryImpl implements JavaScopeFactory { + /** + * Creates the default factory implementation. + * + * + * @generated + */ + public static JavaScopeFactory init() { + try { + JavaScopeFactory theJavaScopeFactory = (JavaScopeFactory)EPackage.Registry.INSTANCE.getEFactory("http:///com/ibm/wala/wala.ecore.java.scope"); + if (theJavaScopeFactory != null) { + return theJavaScopeFactory; + } + } + catch (Exception exception) { + EcorePlugin.INSTANCE.log(exception); + } + return new JavaScopeFactoryImpl(); + } + + /** + * Creates an instance of the factory. + * + * + * @generated + */ + public JavaScopeFactoryImpl() { + super(); + } + + /** + * + * + * @generated + */ + public EObject create(EClass eClass) { + switch (eClass.getClassifierID()) { + case JavaScopePackage.EJAVA_ANALYSIS_SCOPE: return createEJavaAnalysisScope(); + case JavaScopePackage.ECLASS_LOADER: return createEClassLoader(); + case JavaScopePackage.EBUILT_IN_MODULE: return createEBuiltInModule(); + case JavaScopePackage.EJAR_FILE: return createEJarFile(); + case JavaScopePackage.EFILE: return createEFile(); + case JavaScopePackage.ECLASS_FILE: return createEClassFile(); + case JavaScopePackage.ESOURCE_FILE: return createESourceFile(); + case JavaScopePackage.ECLASSPATH: return createEClasspath(); + default: + throw new IllegalArgumentException("The class '" + eClass.getName() + "' is not a valid classifier"); + } + } + + /** + * + * + * @generated + */ + public Object createFromString(EDataType eDataType, String initialValue) { + switch (eDataType.getClassifierID()) { + case JavaScopePackage.EBUILT_IN_RESOURCE: + return createEBuiltInResourceFromString(eDataType, initialValue); + case JavaScopePackage.ESTANDARD_CLASS_LOADER: + return createEStandardClassLoaderFromString(eDataType, initialValue); + default: + throw new IllegalArgumentException("The datatype '" + eDataType.getName() + "' is not a valid classifier"); + } + } + + /** + * + * + * @generated + */ + public String convertToString(EDataType eDataType, Object instanceValue) { + switch (eDataType.getClassifierID()) { + case JavaScopePackage.EBUILT_IN_RESOURCE: + return convertEBuiltInResourceToString(eDataType, instanceValue); + case JavaScopePackage.ESTANDARD_CLASS_LOADER: + return convertEStandardClassLoaderToString(eDataType, instanceValue); + default: + throw new IllegalArgumentException("The datatype '" + eDataType.getName() + "' is not a valid classifier"); + } + } + + /** + * + * + * @generated + */ + public EJavaAnalysisScope createEJavaAnalysisScope() { + EJavaAnalysisScopeImpl eJavaAnalysisScope = new EJavaAnalysisScopeImpl(); + return eJavaAnalysisScope; + } + + /** + * + * + * @generated + */ + public EClassLoader createEClassLoader() { + EClassLoaderImpl eClassLoader = new EClassLoaderImpl(); + return eClassLoader; + } + + /** + * + * + * @generated + */ + public EBuiltInModule createEBuiltInModule() { + EBuiltInModuleImpl eBuiltInModule = new EBuiltInModuleImpl(); + return eBuiltInModule; + } + + /** + * + * + * @generated + */ + public EJarFile createEJarFile() { + EJarFileImpl eJarFile = new EJarFileImpl(); + return eJarFile; + } + + /** + * + * + * @generated + */ + public EFile createEFile() { + EFileImpl eFile = new EFileImpl(); + return eFile; + } + + /** + * + * + * @generated + */ + public EClassFile createEClassFile() { + EClassFileImpl eClassFile = new EClassFileImpl(); + return eClassFile; + } + + /** + * + * + * @generated + */ + public ESourceFile createESourceFile() { + ESourceFileImpl eSourceFile = new ESourceFileImpl(); + return eSourceFile; + } + + /** + * + * + * @generated + */ + public EClasspath createEClasspath() { + EClasspathImpl eClasspath = new EClasspathImpl(); + return eClasspath; + } + + /** + * + * + * @generated + */ + public EBuiltInResource createEBuiltInResourceFromString(EDataType eDataType, String initialValue) { + EBuiltInResource result = EBuiltInResource.get(initialValue); + if (result == null) throw new IllegalArgumentException("The value '" + initialValue + "' is not a valid enumerator of '" + eDataType.getName() + "'"); + return result; + } + + /** + * + * + * @generated + */ + public String convertEBuiltInResourceToString(EDataType eDataType, Object instanceValue) { + return instanceValue == null ? null : instanceValue.toString(); + } + + /** + * + * + * @generated + */ + public EStandardClassLoader createEStandardClassLoaderFromString(EDataType eDataType, String initialValue) { + EStandardClassLoader result = EStandardClassLoader.get(initialValue); + if (result == null) throw new IllegalArgumentException("The value '" + initialValue + "' is not a valid enumerator of '" + eDataType.getName() + "'"); + return result; + } + + /** + * + * + * @generated + */ + public String convertEStandardClassLoaderToString(EDataType eDataType, Object instanceValue) { + return instanceValue == null ? null : instanceValue.toString(); + } + + /** + * + * + * @generated + */ + public JavaScopePackage getJavaScopePackage() { + return (JavaScopePackage)getEPackage(); + } + + /** + * + * + * @deprecated + * @generated + */ + public static JavaScopePackage getPackage() { + return JavaScopePackage.eINSTANCE; + } + +} //JavaScopeFactoryImpl diff --git a/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/impl/JavaScopePackageImpl.java b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/impl/JavaScopePackageImpl.java new file mode 100644 index 000000000..189a95f52 --- /dev/null +++ b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/impl/JavaScopePackageImpl.java @@ -0,0 +1,542 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java.scope.impl; + +import com.ibm.wala.ecore.common.CommonPackage; + +import com.ibm.wala.ecore.common.impl.CommonPackageImpl; + +import com.ibm.wala.ecore.graph.GraphPackage; + +import com.ibm.wala.ecore.graph.impl.GraphPackageImpl; + +import com.ibm.wala.ecore.j2ee.scope.J2EEScopePackage; + +import com.ibm.wala.ecore.j2ee.scope.impl.J2EEScopePackageImpl; + +import com.ibm.wala.ecore.java.JavaPackage; + +import com.ibm.wala.ecore.java.callGraph.CallGraphPackage; + +import com.ibm.wala.ecore.java.callGraph.impl.CallGraphPackageImpl; + +import com.ibm.wala.ecore.java.impl.JavaPackageImpl; + +import com.ibm.wala.ecore.java.pointerAnalysis.PointerAnalysisPackage; + +import com.ibm.wala.ecore.java.pointerAnalysis.impl.PointerAnalysisPackageImpl; + +import com.ibm.wala.ecore.java.scope.EBuiltInModule; +import com.ibm.wala.ecore.java.scope.EBuiltInResource; +import com.ibm.wala.ecore.java.scope.EClassFile; +import com.ibm.wala.ecore.java.scope.EClassLoader; +import com.ibm.wala.ecore.java.scope.EClasspath; +import com.ibm.wala.ecore.java.scope.EFile; +import com.ibm.wala.ecore.java.scope.EJarFile; +import com.ibm.wala.ecore.java.scope.EJavaAnalysisScope; +import com.ibm.wala.ecore.java.scope.EModule; +import com.ibm.wala.ecore.java.scope.ESourceFile; +import com.ibm.wala.ecore.java.scope.EStandardClassLoader; +import com.ibm.wala.ecore.java.scope.JavaScopeFactory; +import com.ibm.wala.ecore.java.scope.JavaScopePackage; + +import com.ibm.wala.ecore.perf.PerfPackage; + +import com.ibm.wala.ecore.perf.impl.PerfPackageImpl; + +import com.ibm.wala.ecore.regex.RegexPackage; + +import com.ibm.wala.ecore.regex.impl.RegexPackageImpl; + +import org.eclipse.emf.ecore.EAttribute; +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EEnum; +import org.eclipse.emf.ecore.EPackage; +import org.eclipse.emf.ecore.EReference; + +import org.eclipse.emf.ecore.impl.EPackageImpl; + +/** + * + * An implementation of the model Package. + * + * @generated + */ +public class JavaScopePackageImpl extends EPackageImpl implements JavaScopePackage { + /** + * + * + * @generated + */ + private EClass eJavaAnalysisScopeEClass = null; + + /** + * + * + * @generated + */ + private EClass eClassLoaderEClass = null; + + /** + * + * + * @generated + */ + private EClass eModuleEClass = null; + + /** + * + * + * @generated + */ + private EClass eBuiltInModuleEClass = null; + + /** + * + * + * @generated + */ + private EClass eJarFileEClass = null; + + /** + * + * + * @generated + */ + private EClass eFileEClass = null; + + /** + * + * + * @generated + */ + private EClass eClassFileEClass = null; + + /** + * + * + * @generated + */ + private EClass eSourceFileEClass = null; + + /** + * + * + * @generated + */ + private EClass eClasspathEClass = null; + + /** + * + * + * @generated + */ + private EEnum eBuiltInResourceEEnum = null; + + /** + * + * + * @generated + */ + private EEnum eStandardClassLoaderEEnum = null; + + /** + * Creates an instance of the model Package, registered with + * {@link org.eclipse.emf.ecore.EPackage.Registry EPackage.Registry} by the package + * package URI value. + *

                              Note: the correct way to create the package is via the static + * factory method {@link #init init()}, which also performs + * initialization of the package, or returns the registered package, + * if one already exists. + * + * + * @see org.eclipse.emf.ecore.EPackage.Registry + * @see com.ibm.wala.ecore.java.scope.JavaScopePackage#eNS_URI + * @see #init() + * @generated + */ + private JavaScopePackageImpl() { + super(eNS_URI, JavaScopeFactory.eINSTANCE); + } + + /** + * + * + * @generated + */ + private static boolean isInited = false; + + /** + * Creates, registers, and initializes the Package for this + * model, and for any others upon which it depends. Simple + * dependencies are satisfied by calling this method on all + * dependent packages before doing anything else. This method drives + * initialization for interdependent packages directly, in parallel + * with this package, itself. + *

                              Of this package and its interdependencies, all packages which + * have not yet been registered by their URI values are first created + * and registered. The packages are then initialized in two steps: + * meta-model objects for all of the packages are created before any + * are initialized, since one package's meta-model objects may refer to + * those of another. + *

                              Invocation of this method will not affect any packages that have + * already been initialized. + * + * + * @see #eNS_URI + * @see #createPackageContents() + * @see #initializePackageContents() + * @generated + */ + public static JavaScopePackage init() { + if (isInited) return (JavaScopePackage)EPackage.Registry.INSTANCE.getEPackage(JavaScopePackage.eNS_URI); + + // Obtain or create and register package + JavaScopePackageImpl theJavaScopePackage = (JavaScopePackageImpl)(EPackage.Registry.INSTANCE.getEPackage(eNS_URI) instanceof JavaScopePackageImpl ? EPackage.Registry.INSTANCE.getEPackage(eNS_URI) : new JavaScopePackageImpl()); + + isInited = true; + + // Obtain or create and register interdependencies + GraphPackageImpl theGraphPackage = (GraphPackageImpl)(EPackage.Registry.INSTANCE.getEPackage(GraphPackage.eNS_URI) instanceof GraphPackageImpl ? EPackage.Registry.INSTANCE.getEPackage(GraphPackage.eNS_URI) : GraphPackage.eINSTANCE); + CommonPackageImpl theCommonPackage = (CommonPackageImpl)(EPackage.Registry.INSTANCE.getEPackage(CommonPackage.eNS_URI) instanceof CommonPackageImpl ? EPackage.Registry.INSTANCE.getEPackage(CommonPackage.eNS_URI) : CommonPackage.eINSTANCE); + RegexPackageImpl theRegexPackage = (RegexPackageImpl)(EPackage.Registry.INSTANCE.getEPackage(RegexPackage.eNS_URI) instanceof RegexPackageImpl ? EPackage.Registry.INSTANCE.getEPackage(RegexPackage.eNS_URI) : RegexPackage.eINSTANCE); + PerfPackageImpl thePerfPackage = (PerfPackageImpl)(EPackage.Registry.INSTANCE.getEPackage(PerfPackage.eNS_URI) instanceof PerfPackageImpl ? EPackage.Registry.INSTANCE.getEPackage(PerfPackage.eNS_URI) : PerfPackage.eINSTANCE); + JavaPackageImpl theJavaPackage = (JavaPackageImpl)(EPackage.Registry.INSTANCE.getEPackage(JavaPackage.eNS_URI) instanceof JavaPackageImpl ? EPackage.Registry.INSTANCE.getEPackage(JavaPackage.eNS_URI) : JavaPackage.eINSTANCE); + CallGraphPackageImpl theCallGraphPackage = (CallGraphPackageImpl)(EPackage.Registry.INSTANCE.getEPackage(CallGraphPackage.eNS_URI) instanceof CallGraphPackageImpl ? EPackage.Registry.INSTANCE.getEPackage(CallGraphPackage.eNS_URI) : CallGraphPackage.eINSTANCE); + PointerAnalysisPackageImpl thePointerAnalysisPackage = (PointerAnalysisPackageImpl)(EPackage.Registry.INSTANCE.getEPackage(PointerAnalysisPackage.eNS_URI) instanceof PointerAnalysisPackageImpl ? EPackage.Registry.INSTANCE.getEPackage(PointerAnalysisPackage.eNS_URI) : PointerAnalysisPackage.eINSTANCE); + J2EEScopePackageImpl theJ2EEScopePackage = (J2EEScopePackageImpl)(EPackage.Registry.INSTANCE.getEPackage(J2EEScopePackage.eNS_URI) instanceof J2EEScopePackageImpl ? EPackage.Registry.INSTANCE.getEPackage(J2EEScopePackage.eNS_URI) : J2EEScopePackage.eINSTANCE); + + // Create package meta-data objects + theJavaScopePackage.createPackageContents(); + theGraphPackage.createPackageContents(); + theCommonPackage.createPackageContents(); + theRegexPackage.createPackageContents(); + thePerfPackage.createPackageContents(); + theJavaPackage.createPackageContents(); + theCallGraphPackage.createPackageContents(); + thePointerAnalysisPackage.createPackageContents(); + theJ2EEScopePackage.createPackageContents(); + + // Initialize created meta-data + theJavaScopePackage.initializePackageContents(); + theGraphPackage.initializePackageContents(); + theCommonPackage.initializePackageContents(); + theRegexPackage.initializePackageContents(); + thePerfPackage.initializePackageContents(); + theJavaPackage.initializePackageContents(); + theCallGraphPackage.initializePackageContents(); + thePointerAnalysisPackage.initializePackageContents(); + theJ2EEScopePackage.initializePackageContents(); + + // Mark meta-data to indicate it can't be changed + theJavaScopePackage.freeze(); + + return theJavaScopePackage; + } + + /** + * + * + * @generated + */ + public EClass getEJavaAnalysisScope() { + return eJavaAnalysisScopeEClass; + } + + /** + * + * + * @generated + */ + public EReference getEJavaAnalysisScope_Loaders() { + return (EReference)eJavaAnalysisScopeEClass.getEStructuralFeatures().get(0); + } + + /** + * + * + * @generated + */ + public EAttribute getEJavaAnalysisScope_ExclusionFileName() { + return (EAttribute)eJavaAnalysisScopeEClass.getEStructuralFeatures().get(1); + } + + /** + * + * + * @generated + */ + public EClass getEClassLoader() { + return eClassLoaderEClass; + } + + /** + * + * + * @generated + */ + public EReference getEClassLoader_Modules() { + return (EReference)eClassLoaderEClass.getEStructuralFeatures().get(0); + } + + /** + * + * + * @generated + */ + public EAttribute getEClassLoader_LoaderName() { + return (EAttribute)eClassLoaderEClass.getEStructuralFeatures().get(1); + } + + /** + * + * + * @generated + */ + public EClass getEModule() { + return eModuleEClass; + } + + /** + * + * + * @generated + */ + public EClass getEBuiltInModule() { + return eBuiltInModuleEClass; + } + + /** + * + * + * @generated + */ + public EAttribute getEBuiltInModule_Id() { + return (EAttribute)eBuiltInModuleEClass.getEStructuralFeatures().get(0); + } + + /** + * + * + * @generated + */ + public EClass getEJarFile() { + return eJarFileEClass; + } + + /** + * + * + * @generated + */ + public EAttribute getEJarFile_Url() { + return (EAttribute)eJarFileEClass.getEStructuralFeatures().get(0); + } + + /** + * + * + * @generated + */ + public EClass getEFile() { + return eFileEClass; + } + + /** + * + * + * @generated + */ + public EAttribute getEFile_Url() { + return (EAttribute)eFileEClass.getEStructuralFeatures().get(0); + } + + /** + * + * + * @generated + */ + public EClass getEClassFile() { + return eClassFileEClass; + } + + /** + * + * + * @generated + */ + public EClass getESourceFile() { + return eSourceFileEClass; + } + + /** + * + * + * @generated + */ + public EClass getEClasspath() { + return eClasspathEClass; + } + + /** + * + * + * @generated + */ + public EAttribute getEClasspath_String() { + return (EAttribute)eClasspathEClass.getEStructuralFeatures().get(0); + } + + /** + * + * + * @generated + */ + public EEnum getEBuiltInResource() { + return eBuiltInResourceEEnum; + } + + /** + * + * + * @generated + */ + public EEnum getEStandardClassLoader() { + return eStandardClassLoaderEEnum; + } + + /** + * + * + * @generated + */ + public JavaScopeFactory getJavaScopeFactory() { + return (JavaScopeFactory)getEFactoryInstance(); + } + + /** + * + * + * @generated + */ + private boolean isCreated = false; + + /** + * Creates the meta-model objects for the package. This method is + * guarded to have no affect on any invocation but its first. + * + * + * @generated + */ + public void createPackageContents() { + if (isCreated) return; + isCreated = true; + + // Create classes and their features + eJavaAnalysisScopeEClass = createEClass(EJAVA_ANALYSIS_SCOPE); + createEReference(eJavaAnalysisScopeEClass, EJAVA_ANALYSIS_SCOPE__LOADERS); + createEAttribute(eJavaAnalysisScopeEClass, EJAVA_ANALYSIS_SCOPE__EXCLUSION_FILE_NAME); + + eClassLoaderEClass = createEClass(ECLASS_LOADER); + createEReference(eClassLoaderEClass, ECLASS_LOADER__MODULES); + createEAttribute(eClassLoaderEClass, ECLASS_LOADER__LOADER_NAME); + + eModuleEClass = createEClass(EMODULE); + + eBuiltInModuleEClass = createEClass(EBUILT_IN_MODULE); + createEAttribute(eBuiltInModuleEClass, EBUILT_IN_MODULE__ID); + + eJarFileEClass = createEClass(EJAR_FILE); + createEAttribute(eJarFileEClass, EJAR_FILE__URL); + + eFileEClass = createEClass(EFILE); + createEAttribute(eFileEClass, EFILE__URL); + + eClassFileEClass = createEClass(ECLASS_FILE); + + eSourceFileEClass = createEClass(ESOURCE_FILE); + + eClasspathEClass = createEClass(ECLASSPATH); + createEAttribute(eClasspathEClass, ECLASSPATH__STRING); + + // Create enums + eBuiltInResourceEEnum = createEEnum(EBUILT_IN_RESOURCE); + eStandardClassLoaderEEnum = createEEnum(ESTANDARD_CLASS_LOADER); + } + + /** + * + * + * @generated + */ + private boolean isInitialized = false; + + /** + * Complete the initialization of the package and its meta-model. This + * method is guarded to have no affect on any invocation but its first. + * + * + * @generated + */ + public void initializePackageContents() { + if (isInitialized) return; + isInitialized = true; + + // Initialize package + setName(eNAME); + setNsPrefix(eNS_PREFIX); + setNsURI(eNS_URI); + + // Add supertypes to classes + eBuiltInModuleEClass.getESuperTypes().add(this.getEModule()); + eJarFileEClass.getESuperTypes().add(this.getEModule()); + eFileEClass.getESuperTypes().add(this.getEModule()); + eClassFileEClass.getESuperTypes().add(this.getEFile()); + eSourceFileEClass.getESuperTypes().add(this.getEFile()); + + // Initialize classes and features; add operations and parameters + initEClass(eJavaAnalysisScopeEClass, EJavaAnalysisScope.class, "EJavaAnalysisScope", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); + initEReference(getEJavaAnalysisScope_Loaders(), this.getEClassLoader(), null, "loaders", null, 1, -1, EJavaAnalysisScope.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, IS_COMPOSITE, !IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); + initEAttribute(getEJavaAnalysisScope_ExclusionFileName(), ecorePackage.getEString(), "exclusionFileName", null, 0, 1, EJavaAnalysisScope.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); + + initEClass(eClassLoaderEClass, EClassLoader.class, "EClassLoader", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); + initEReference(getEClassLoader_Modules(), this.getEModule(), null, "modules", null, 1, -1, EClassLoader.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, IS_COMPOSITE, !IS_RESOLVE_PROXIES, !IS_UNSETTABLE, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); + initEAttribute(getEClassLoader_LoaderName(), ecorePackage.getEString(), "loaderName", null, 0, 1, EClassLoader.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); + + initEClass(eModuleEClass, EModule.class, "EModule", IS_ABSTRACT, IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); + + initEClass(eBuiltInModuleEClass, EBuiltInModule.class, "EBuiltInModule", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); + initEAttribute(getEBuiltInModule_Id(), this.getEBuiltInResource(), "id", null, 1, 1, EBuiltInModule.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); + + initEClass(eJarFileEClass, EJarFile.class, "EJarFile", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); + initEAttribute(getEJarFile_Url(), ecorePackage.getEString(), "url", null, 1, 1, EJarFile.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); + + initEClass(eFileEClass, EFile.class, "EFile", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); + initEAttribute(getEFile_Url(), ecorePackage.getEString(), "url", null, 1, 1, EFile.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); + + initEClass(eClassFileEClass, EClassFile.class, "EClassFile", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); + + initEClass(eSourceFileEClass, ESourceFile.class, "ESourceFile", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); + + initEClass(eClasspathEClass, EClasspath.class, "EClasspath", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); + initEAttribute(getEClasspath_String(), ecorePackage.getEString(), "string", null, 1, 1, EClasspath.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); + + // Initialize enums and add enum literals + initEEnum(eBuiltInResourceEEnum, EBuiltInResource.class, "EBuiltInResource"); + addEEnumLiteral(eBuiltInResourceEEnum, EBuiltInResource.DEFAULT_J2SE_LIBS_LITERAL); + addEEnumLiteral(eBuiltInResourceEEnum, EBuiltInResource.DEFAULT_J2EE_LIBS_LITERAL); + addEEnumLiteral(eBuiltInResourceEEnum, EBuiltInResource.PRIMORDIAL_JAR_MODEL_LITERAL); + addEEnumLiteral(eBuiltInResourceEEnum, EBuiltInResource.EXTENSION_JAR_MODEL_LITERAL); + + initEEnum(eStandardClassLoaderEEnum, EStandardClassLoader.class, "EStandardClassLoader"); + addEEnumLiteral(eStandardClassLoaderEEnum, EStandardClassLoader.PRIMORDIAL_LITERAL); + addEEnumLiteral(eStandardClassLoaderEEnum, EStandardClassLoader.EXTENSION_LITERAL); + addEEnumLiteral(eStandardClassLoaderEEnum, EStandardClassLoader.APPLICATION_LITERAL); + addEEnumLiteral(eStandardClassLoaderEEnum, EStandardClassLoader.SYNTHETIC_LITERAL); + } + +} //JavaScopePackageImpl diff --git a/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/util/JavaScopeAdapterFactory.java b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/util/JavaScopeAdapterFactory.java new file mode 100644 index 000000000..fced91907 --- /dev/null +++ b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/util/JavaScopeAdapterFactory.java @@ -0,0 +1,256 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java.scope.util; + +import com.ibm.wala.ecore.java.scope.*; + +import org.eclipse.emf.common.notify.Adapter; +import org.eclipse.emf.common.notify.Notifier; + +import org.eclipse.emf.common.notify.impl.AdapterFactoryImpl; + +import org.eclipse.emf.ecore.EObject; + +/** + * + * The Adapter Factory for the model. + * It provides an adapter createXXX method for each class of the model. + * + * @see com.ibm.wala.ecore.java.scope.JavaScopePackage + * @generated + */ +public class JavaScopeAdapterFactory extends AdapterFactoryImpl { + /** + * The cached model package. + * + * + * @generated + */ + protected static JavaScopePackage modelPackage; + + /** + * Creates an instance of the adapter factory. + * + * + * @generated + */ + public JavaScopeAdapterFactory() { + if (modelPackage == null) { + modelPackage = JavaScopePackage.eINSTANCE; + } + } + + /** + * Returns whether this factory is applicable for the type of the object. + * + * This implementation returns true if the object is either the model's package or is an instance object of the model. + * + * @return whether this factory is applicable for the type of the object. + * @generated + */ + public boolean isFactoryForType(Object object) { + if (object == modelPackage) { + return true; + } + if (object instanceof EObject) { + return ((EObject)object).eClass().getEPackage() == modelPackage; + } + return false; + } + + /** + * The switch the delegates to the createXXX methods. + * + * + * @generated + */ + protected JavaScopeSwitch modelSwitch = + new JavaScopeSwitch() { + public Object caseEJavaAnalysisScope(EJavaAnalysisScope object) { + return createEJavaAnalysisScopeAdapter(); + } + public Object caseEClassLoader(EClassLoader object) { + return createEClassLoaderAdapter(); + } + public Object caseEModule(EModule object) { + return createEModuleAdapter(); + } + public Object caseEBuiltInModule(EBuiltInModule object) { + return createEBuiltInModuleAdapter(); + } + public Object caseEJarFile(EJarFile object) { + return createEJarFileAdapter(); + } + public Object caseEFile(EFile object) { + return createEFileAdapter(); + } + public Object caseEClassFile(EClassFile object) { + return createEClassFileAdapter(); + } + public Object caseESourceFile(ESourceFile object) { + return createESourceFileAdapter(); + } + public Object caseEClasspath(EClasspath object) { + return createEClasspathAdapter(); + } + public Object defaultCase(EObject object) { + return createEObjectAdapter(); + } + }; + + /** + * Creates an adapter for the target. + * + * + * @param target the object to adapt. + * @return the adapter for the target. + * @generated + */ + public Adapter createAdapter(Notifier target) { + return (Adapter)modelSwitch.doSwitch((EObject)target); + } + + + /** + * Creates a new adapter for an object of class '{@link com.ibm.wala.ecore.java.scope.EJavaAnalysisScope EJava Analysis Scope}'. + * + * This default implementation returns null so that we can easily ignore cases; + * it's useful to ignore a case when inheritance will catch all the cases anyway. + * + * @return the new adapter. + * @see com.ibm.wala.ecore.java.scope.EJavaAnalysisScope + * @generated + */ + public Adapter createEJavaAnalysisScopeAdapter() { + return null; + } + + /** + * Creates a new adapter for an object of class '{@link com.ibm.wala.ecore.java.scope.EClassLoader EClass Loader}'. + * + * This default implementation returns null so that we can easily ignore cases; + * it's useful to ignore a case when inheritance will catch all the cases anyway. + * + * @return the new adapter. + * @see com.ibm.wala.ecore.java.scope.EClassLoader + * @generated + */ + public Adapter createEClassLoaderAdapter() { + return null; + } + + /** + * Creates a new adapter for an object of class '{@link com.ibm.wala.ecore.java.scope.EModule EModule}'. + * + * This default implementation returns null so that we can easily ignore cases; + * it's useful to ignore a case when inheritance will catch all the cases anyway. + * + * @return the new adapter. + * @see com.ibm.wala.ecore.java.scope.EModule + * @generated + */ + public Adapter createEModuleAdapter() { + return null; + } + + /** + * Creates a new adapter for an object of class '{@link com.ibm.wala.ecore.java.scope.EBuiltInModule EBuilt In Module}'. + * + * This default implementation returns null so that we can easily ignore cases; + * it's useful to ignore a case when inheritance will catch all the cases anyway. + * + * @return the new adapter. + * @see com.ibm.wala.ecore.java.scope.EBuiltInModule + * @generated + */ + public Adapter createEBuiltInModuleAdapter() { + return null; + } + + /** + * Creates a new adapter for an object of class '{@link com.ibm.wala.ecore.java.scope.EJarFile EJar File}'. + * + * This default implementation returns null so that we can easily ignore cases; + * it's useful to ignore a case when inheritance will catch all the cases anyway. + * + * @return the new adapter. + * @see com.ibm.wala.ecore.java.scope.EJarFile + * @generated + */ + public Adapter createEJarFileAdapter() { + return null; + } + + /** + * Creates a new adapter for an object of class '{@link com.ibm.wala.ecore.java.scope.EFile EFile}'. + * + * This default implementation returns null so that we can easily ignore cases; + * it's useful to ignore a case when inheritance will catch all the cases anyway. + * + * @return the new adapter. + * @see com.ibm.wala.ecore.java.scope.EFile + * @generated + */ + public Adapter createEFileAdapter() { + return null; + } + + /** + * Creates a new adapter for an object of class '{@link com.ibm.wala.ecore.java.scope.EClassFile EClass File}'. + * + * This default implementation returns null so that we can easily ignore cases; + * it's useful to ignore a case when inheritance will catch all the cases anyway. + * + * @return the new adapter. + * @see com.ibm.wala.ecore.java.scope.EClassFile + * @generated + */ + public Adapter createEClassFileAdapter() { + return null; + } + + /** + * Creates a new adapter for an object of class '{@link com.ibm.wala.ecore.java.scope.ESourceFile ESource File}'. + * + * This default implementation returns null so that we can easily ignore cases; + * it's useful to ignore a case when inheritance will catch all the cases anyway. + * + * @return the new adapter. + * @see com.ibm.wala.ecore.java.scope.ESourceFile + * @generated + */ + public Adapter createESourceFileAdapter() { + return null; + } + + /** + * Creates a new adapter for an object of class '{@link com.ibm.wala.ecore.java.scope.EClasspath EClasspath}'. + * + * This default implementation returns null so that we can easily ignore cases; + * it's useful to ignore a case when inheritance will catch all the cases anyway. + * + * @return the new adapter. + * @see com.ibm.wala.ecore.java.scope.EClasspath + * @generated + */ + public Adapter createEClasspathAdapter() { + return null; + } + + /** + * Creates a new adapter for the default case. + * + * This default implementation returns null. + * + * @return the new adapter. + * @generated + */ + public Adapter createEObjectAdapter() { + return null; + } + +} //JavaScopeAdapterFactory diff --git a/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/util/JavaScopeSwitch.java b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/util/JavaScopeSwitch.java new file mode 100644 index 000000000..77c43ed52 --- /dev/null +++ b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/scope/util/JavaScopeSwitch.java @@ -0,0 +1,305 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java.scope.util; + +import com.ibm.wala.ecore.java.scope.*; + +import java.util.List; + +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EObject; + +/** + * + * The Switch for the model's inheritance hierarchy. + * It supports the call {@link #doSwitch(EObject) doSwitch(object)} + * to invoke the caseXXX method for each class of the model, + * starting with the actual class of the object + * and proceeding up the inheritance hierarchy + * until a non-null result is returned, + * which is the result of the switch. + * + * @see com.ibm.wala.ecore.java.scope.JavaScopePackage + * @generated + */ +public class JavaScopeSwitch { + /** + * The cached model package + * + * + * @generated + */ + protected static JavaScopePackage modelPackage; + + /** + * Creates an instance of the switch. + * + * + * @generated + */ + public JavaScopeSwitch() { + if (modelPackage == null) { + modelPackage = JavaScopePackage.eINSTANCE; + } + } + + /** + * Calls caseXXX for each class of the model until one returns a non null result; it yields that result. + * + * + * @return the first non-null result returned by a caseXXX call. + * @generated + */ + public Object doSwitch(EObject theEObject) { + return doSwitch(theEObject.eClass(), theEObject); + } + + /** + * Calls caseXXX for each class of the model until one returns a non null result; it yields that result. + * + * + * @return the first non-null result returned by a caseXXX call. + * @generated + */ + protected Object doSwitch(EClass theEClass, EObject theEObject) { + if (theEClass.eContainer() == modelPackage) { + return doSwitch(theEClass.getClassifierID(), theEObject); + } + else { + List eSuperTypes = theEClass.getESuperTypes(); + return + eSuperTypes.isEmpty() ? + defaultCase(theEObject) : + doSwitch((EClass)eSuperTypes.get(0), theEObject); + } + } + + /** + * Calls caseXXX for each class of the model until one returns a non null result; it yields that result. + * + * + * @return the first non-null result returned by a caseXXX call. + * @generated + */ + protected Object doSwitch(int classifierID, EObject theEObject) { + switch (classifierID) { + case JavaScopePackage.EJAVA_ANALYSIS_SCOPE: { + EJavaAnalysisScope eJavaAnalysisScope = (EJavaAnalysisScope)theEObject; + Object result = caseEJavaAnalysisScope(eJavaAnalysisScope); + if (result == null) result = defaultCase(theEObject); + return result; + } + case JavaScopePackage.ECLASS_LOADER: { + EClassLoader eClassLoader = (EClassLoader)theEObject; + Object result = caseEClassLoader(eClassLoader); + if (result == null) result = defaultCase(theEObject); + return result; + } + case JavaScopePackage.EMODULE: { + EModule eModule = (EModule)theEObject; + Object result = caseEModule(eModule); + if (result == null) result = defaultCase(theEObject); + return result; + } + case JavaScopePackage.EBUILT_IN_MODULE: { + EBuiltInModule eBuiltInModule = (EBuiltInModule)theEObject; + Object result = caseEBuiltInModule(eBuiltInModule); + if (result == null) result = caseEModule(eBuiltInModule); + if (result == null) result = defaultCase(theEObject); + return result; + } + case JavaScopePackage.EJAR_FILE: { + EJarFile eJarFile = (EJarFile)theEObject; + Object result = caseEJarFile(eJarFile); + if (result == null) result = caseEModule(eJarFile); + if (result == null) result = defaultCase(theEObject); + return result; + } + case JavaScopePackage.EFILE: { + EFile eFile = (EFile)theEObject; + Object result = caseEFile(eFile); + if (result == null) result = caseEModule(eFile); + if (result == null) result = defaultCase(theEObject); + return result; + } + case JavaScopePackage.ECLASS_FILE: { + EClassFile eClassFile = (EClassFile)theEObject; + Object result = caseEClassFile(eClassFile); + if (result == null) result = caseEFile(eClassFile); + if (result == null) result = caseEModule(eClassFile); + if (result == null) result = defaultCase(theEObject); + return result; + } + case JavaScopePackage.ESOURCE_FILE: { + ESourceFile eSourceFile = (ESourceFile)theEObject; + Object result = caseESourceFile(eSourceFile); + if (result == null) result = caseEFile(eSourceFile); + if (result == null) result = caseEModule(eSourceFile); + if (result == null) result = defaultCase(theEObject); + return result; + } + case JavaScopePackage.ECLASSPATH: { + EClasspath eClasspath = (EClasspath)theEObject; + Object result = caseEClasspath(eClasspath); + if (result == null) result = defaultCase(theEObject); + return result; + } + default: return defaultCase(theEObject); + } + } + + /** + * Returns the result of interpretting the object as an instance of 'EJava Analysis Scope'. + * + * This implementation returns null; + * returning a non-null result will terminate the switch. + * + * @param object the target of the switch. + * @return the result of interpretting the object as an instance of 'EJava Analysis Scope'. + * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject) + * @generated + */ + public Object caseEJavaAnalysisScope(EJavaAnalysisScope object) { + return null; + } + + /** + * Returns the result of interpretting the object as an instance of 'EClass Loader'. + * + * This implementation returns null; + * returning a non-null result will terminate the switch. + * + * @param object the target of the switch. + * @return the result of interpretting the object as an instance of 'EClass Loader'. + * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject) + * @generated + */ + public Object caseEClassLoader(EClassLoader object) { + return null; + } + + /** + * Returns the result of interpretting the object as an instance of 'EModule'. + * + * This implementation returns null; + * returning a non-null result will terminate the switch. + * + * @param object the target of the switch. + * @return the result of interpretting the object as an instance of 'EModule'. + * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject) + * @generated + */ + public Object caseEModule(EModule object) { + return null; + } + + /** + * Returns the result of interpretting the object as an instance of 'EBuilt In Module'. + * + * This implementation returns null; + * returning a non-null result will terminate the switch. + * + * @param object the target of the switch. + * @return the result of interpretting the object as an instance of 'EBuilt In Module'. + * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject) + * @generated + */ + public Object caseEBuiltInModule(EBuiltInModule object) { + return null; + } + + /** + * Returns the result of interpretting the object as an instance of 'EJar File'. + * + * This implementation returns null; + * returning a non-null result will terminate the switch. + * + * @param object the target of the switch. + * @return the result of interpretting the object as an instance of 'EJar File'. + * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject) + * @generated + */ + public Object caseEJarFile(EJarFile object) { + return null; + } + + /** + * Returns the result of interpretting the object as an instance of 'EFile'. + * + * This implementation returns null; + * returning a non-null result will terminate the switch. + * + * @param object the target of the switch. + * @return the result of interpretting the object as an instance of 'EFile'. + * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject) + * @generated + */ + public Object caseEFile(EFile object) { + return null; + } + + /** + * Returns the result of interpretting the object as an instance of 'EClass File'. + * + * This implementation returns null; + * returning a non-null result will terminate the switch. + * + * @param object the target of the switch. + * @return the result of interpretting the object as an instance of 'EClass File'. + * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject) + * @generated + */ + public Object caseEClassFile(EClassFile object) { + return null; + } + + /** + * Returns the result of interpretting the object as an instance of 'ESource File'. + * + * This implementation returns null; + * returning a non-null result will terminate the switch. + * + * @param object the target of the switch. + * @return the result of interpretting the object as an instance of 'ESource File'. + * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject) + * @generated + */ + public Object caseESourceFile(ESourceFile object) { + return null; + } + + /** + * Returns the result of interpretting the object as an instance of 'EClasspath'. + * + * This implementation returns null; + * returning a non-null result will terminate the switch. + * + * @param object the target of the switch. + * @return the result of interpretting the object as an instance of 'EClasspath'. + * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject) + * @generated + */ + public Object caseEClasspath(EClasspath object) { + return null; + } + + /** + * Returns the result of interpretting the object as an instance of 'EObject'. + * + * This implementation returns null; + * returning a non-null result will terminate the switch, but this is the last case anyway. + * + * @param object the target of the switch. + * @return the result of interpretting the object as an instance of 'EObject'. + * @see #doSwitch(org.eclipse.emf.ecore.EObject) + * @generated + */ + public Object defaultCase(EObject object) { + return null; + } + +} //JavaScopeSwitch diff --git a/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/util/JavaAdapterFactory.java b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/util/JavaAdapterFactory.java new file mode 100644 index 000000000..b81541f3d --- /dev/null +++ b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/util/JavaAdapterFactory.java @@ -0,0 +1,261 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java.util; + +import com.ibm.wala.ecore.common.EObjectWithContainerId; + +import com.ibm.wala.ecore.graph.EGraph; +import com.ibm.wala.ecore.graph.ETree; + +import com.ibm.wala.ecore.java.*; + +import org.eclipse.emf.common.notify.Adapter; +import org.eclipse.emf.common.notify.Notifier; + +import org.eclipse.emf.common.notify.impl.AdapterFactoryImpl; + +import org.eclipse.emf.ecore.EObject; + +/** + * + * The Adapter Factory for the model. + * It provides an adapter createXXX method for each class of the model. + * + * @see com.ibm.wala.ecore.java.JavaPackage + * @generated + */ +public class JavaAdapterFactory extends AdapterFactoryImpl { + /** + * The cached model package. + * + * + * @generated + */ + protected static JavaPackage modelPackage; + + /** + * Creates an instance of the adapter factory. + * + * + * @generated + */ + public JavaAdapterFactory() { + if (modelPackage == null) { + modelPackage = JavaPackage.eINSTANCE; + } + } + + /** + * Returns whether this factory is applicable for the type of the object. + * + * This implementation returns true if the object is either the model's package or is an instance object of the model. + * + * @return whether this factory is applicable for the type of the object. + * @generated + */ + public boolean isFactoryForType(Object object) { + if (object == modelPackage) { + return true; + } + if (object instanceof EObject) { + return ((EObject)object).eClass().getEPackage() == modelPackage; + } + return false; + } + + /** + * The switch the delegates to the createXXX methods. + * + * + * @generated + */ + protected JavaSwitch modelSwitch = + new JavaSwitch() { + public Object caseEJavaClass(EJavaClass object) { + return createEJavaClassAdapter(); + } + public Object caseEJavaMethod(EJavaMethod object) { + return createEJavaMethodAdapter(); + } + public Object caseECallSite(ECallSite object) { + return createECallSiteAdapter(); + } + public Object caseEClassHierarchy(EClassHierarchy object) { + return createEClassHierarchyAdapter(); + } + public Object caseEInterfaceHierarchy(EInterfaceHierarchy object) { + return createEInterfaceHierarchyAdapter(); + } + public Object caseETypeHierarchy(ETypeHierarchy object) { + return createETypeHierarchyAdapter(); + } + public Object caseEObjectWithContainerId(EObjectWithContainerId object) { + return createEObjectWithContainerIdAdapter(); + } + public Object caseEGraph(EGraph object) { + return createEGraphAdapter(); + } + public Object caseETree(ETree object) { + return createETreeAdapter(); + } + public Object defaultCase(EObject object) { + return createEObjectAdapter(); + } + }; + + /** + * Creates an adapter for the target. + * + * + * @param target the object to adapt. + * @return the adapter for the target. + * @generated + */ + public Adapter createAdapter(Notifier target) { + return (Adapter)modelSwitch.doSwitch((EObject)target); + } + + + /** + * Creates a new adapter for an object of class '{@link com.ibm.wala.ecore.java.EJavaClass EJava Class}'. + * + * This default implementation returns null so that we can easily ignore cases; + * it's useful to ignore a case when inheritance will catch all the cases anyway. + * + * @return the new adapter. + * @see com.ibm.wala.ecore.java.EJavaClass + * @generated + */ + public Adapter createEJavaClassAdapter() { + return null; + } + + /** + * Creates a new adapter for an object of class '{@link com.ibm.wala.ecore.java.EJavaMethod EJava Method}'. + * + * This default implementation returns null so that we can easily ignore cases; + * it's useful to ignore a case when inheritance will catch all the cases anyway. + * + * @return the new adapter. + * @see com.ibm.wala.ecore.java.EJavaMethod + * @generated + */ + public Adapter createEJavaMethodAdapter() { + return null; + } + + /** + * Creates a new adapter for an object of class '{@link com.ibm.wala.ecore.java.ECallSite ECall Site}'. + * + * This default implementation returns null so that we can easily ignore cases; + * it's useful to ignore a case when inheritance will catch all the cases anyway. + * + * @return the new adapter. + * @see com.ibm.wala.ecore.java.ECallSite + * @generated + */ + public Adapter createECallSiteAdapter() { + return null; + } + + /** + * Creates a new adapter for an object of class '{@link com.ibm.wala.ecore.java.EClassHierarchy EClass Hierarchy}'. + * + * This default implementation returns null so that we can easily ignore cases; + * it's useful to ignore a case when inheritance will catch all the cases anyway. + * + * @return the new adapter. + * @see com.ibm.wala.ecore.java.EClassHierarchy + * @generated + */ + public Adapter createEClassHierarchyAdapter() { + return null; + } + + /** + * Creates a new adapter for an object of class '{@link com.ibm.wala.ecore.java.EInterfaceHierarchy EInterface Hierarchy}'. + * + * This default implementation returns null so that we can easily ignore cases; + * it's useful to ignore a case when inheritance will catch all the cases anyway. + * + * @return the new adapter. + * @see com.ibm.wala.ecore.java.EInterfaceHierarchy + * @generated + */ + public Adapter createEInterfaceHierarchyAdapter() { + return null; + } + + /** + * Creates a new adapter for an object of class '{@link com.ibm.wala.ecore.java.ETypeHierarchy EType Hierarchy}'. + * + * This default implementation returns null so that we can easily ignore cases; + * it's useful to ignore a case when inheritance will catch all the cases anyway. + * + * @return the new adapter. + * @see com.ibm.wala.ecore.java.ETypeHierarchy + * @generated + */ + public Adapter createETypeHierarchyAdapter() { + return null; + } + + /** + * Creates a new adapter for an object of class '{@link com.ibm.wala.ecore.common.EObjectWithContainerId EObject With Container Id}'. + * + * This default implementation returns null so that we can easily ignore cases; + * it's useful to ignore a case when inheritance will catch all the cases anyway. + * + * @return the new adapter. + * @see com.ibm.wala.ecore.common.EObjectWithContainerId + * @generated + */ + public Adapter createEObjectWithContainerIdAdapter() { + return null; + } + + /** + * Creates a new adapter for an object of class '{@link com.ibm.wala.ecore.graph.EGraph EGraph}'. + * + * This default implementation returns null so that we can easily ignore cases; + * it's useful to ignore a case when inheritance will catch all the cases anyway. + * + * @return the new adapter. + * @see com.ibm.wala.ecore.graph.EGraph + * @generated + */ + public Adapter createEGraphAdapter() { + return null; + } + + /** + * Creates a new adapter for an object of class '{@link com.ibm.wala.ecore.graph.ETree ETree}'. + * + * This default implementation returns null so that we can easily ignore cases; + * it's useful to ignore a case when inheritance will catch all the cases anyway. + * + * @return the new adapter. + * @see com.ibm.wala.ecore.graph.ETree + * @generated + */ + public Adapter createETreeAdapter() { + return null; + } + + /** + * Creates a new adapter for the default case. + * + * This default implementation returns null. + * + * @return the new adapter. + * @generated + */ + public Adapter createEObjectAdapter() { + return null; + } + +} //JavaAdapterFactory diff --git a/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/util/JavaSwitch.java b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/util/JavaSwitch.java new file mode 100644 index 000000000..2b49b4729 --- /dev/null +++ b/com.ibm.wala.emf/src/com/ibm/wala/ecore/java/util/JavaSwitch.java @@ -0,0 +1,291 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.java.util; + +import com.ibm.wala.ecore.common.EObjectWithContainerId; + +import com.ibm.wala.ecore.graph.EGraph; +import com.ibm.wala.ecore.graph.ETree; + +import com.ibm.wala.ecore.java.*; + +import java.util.List; + +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EObject; + +/** + * + * The Switch for the model's inheritance hierarchy. + * It supports the call {@link #doSwitch(EObject) doSwitch(object)} + * to invoke the caseXXX method for each class of the model, + * starting with the actual class of the object + * and proceeding up the inheritance hierarchy + * until a non-null result is returned, + * which is the result of the switch. + * + * @see com.ibm.wala.ecore.java.JavaPackage + * @generated + */ +public class JavaSwitch { + /** + * The cached model package + * + * + * @generated + */ + protected static JavaPackage modelPackage; + + /** + * Creates an instance of the switch. + * + * + * @generated + */ + public JavaSwitch() { + if (modelPackage == null) { + modelPackage = JavaPackage.eINSTANCE; + } + } + + /** + * Calls caseXXX for each class of the model until one returns a non null result; it yields that result. + * + * + * @return the first non-null result returned by a caseXXX call. + * @generated + */ + public Object doSwitch(EObject theEObject) { + return doSwitch(theEObject.eClass(), theEObject); + } + + /** + * Calls caseXXX for each class of the model until one returns a non null result; it yields that result. + * + * + * @return the first non-null result returned by a caseXXX call. + * @generated + */ + protected Object doSwitch(EClass theEClass, EObject theEObject) { + if (theEClass.eContainer() == modelPackage) { + return doSwitch(theEClass.getClassifierID(), theEObject); + } + else { + List eSuperTypes = theEClass.getESuperTypes(); + return + eSuperTypes.isEmpty() ? + defaultCase(theEObject) : + doSwitch((EClass)eSuperTypes.get(0), theEObject); + } + } + + /** + * Calls caseXXX for each class of the model until one returns a non null result; it yields that result. + * + * + * @return the first non-null result returned by a caseXXX call. + * @generated + */ + protected Object doSwitch(int classifierID, EObject theEObject) { + switch (classifierID) { + case JavaPackage.EJAVA_CLASS: { + EJavaClass eJavaClass = (EJavaClass)theEObject; + Object result = caseEJavaClass(eJavaClass); + if (result == null) result = caseEObjectWithContainerId(eJavaClass); + if (result == null) result = defaultCase(theEObject); + return result; + } + case JavaPackage.EJAVA_METHOD: { + EJavaMethod eJavaMethod = (EJavaMethod)theEObject; + Object result = caseEJavaMethod(eJavaMethod); + if (result == null) result = caseEObjectWithContainerId(eJavaMethod); + if (result == null) result = defaultCase(theEObject); + return result; + } + case JavaPackage.ECALL_SITE: { + ECallSite eCallSite = (ECallSite)theEObject; + Object result = caseECallSite(eCallSite); + if (result == null) result = caseEObjectWithContainerId(eCallSite); + if (result == null) result = defaultCase(theEObject); + return result; + } + case JavaPackage.ECLASS_HIERARCHY: { + EClassHierarchy eClassHierarchy = (EClassHierarchy)theEObject; + Object result = caseEClassHierarchy(eClassHierarchy); + if (result == null) result = caseETree(eClassHierarchy); + if (result == null) result = caseEGraph(eClassHierarchy); + if (result == null) result = defaultCase(theEObject); + return result; + } + case JavaPackage.EINTERFACE_HIERARCHY: { + EInterfaceHierarchy eInterfaceHierarchy = (EInterfaceHierarchy)theEObject; + Object result = caseEInterfaceHierarchy(eInterfaceHierarchy); + if (result == null) result = caseEGraph(eInterfaceHierarchy); + if (result == null) result = defaultCase(theEObject); + return result; + } + case JavaPackage.ETYPE_HIERARCHY: { + ETypeHierarchy eTypeHierarchy = (ETypeHierarchy)theEObject; + Object result = caseETypeHierarchy(eTypeHierarchy); + if (result == null) result = defaultCase(theEObject); + return result; + } + default: return defaultCase(theEObject); + } + } + + /** + * Returns the result of interpretting the object as an instance of 'EJava Class'. + * + * This implementation returns null; + * returning a non-null result will terminate the switch. + * + * @param object the target of the switch. + * @return the result of interpretting the object as an instance of 'EJava Class'. + * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject) + * @generated + */ + public Object caseEJavaClass(EJavaClass object) { + return null; + } + + /** + * Returns the result of interpretting the object as an instance of 'EJava Method'. + * + * This implementation returns null; + * returning a non-null result will terminate the switch. + * + * @param object the target of the switch. + * @return the result of interpretting the object as an instance of 'EJava Method'. + * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject) + * @generated + */ + public Object caseEJavaMethod(EJavaMethod object) { + return null; + } + + /** + * Returns the result of interpretting the object as an instance of 'ECall Site'. + * + * This implementation returns null; + * returning a non-null result will terminate the switch. + * + * @param object the target of the switch. + * @return the result of interpretting the object as an instance of 'ECall Site'. + * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject) + * @generated + */ + public Object caseECallSite(ECallSite object) { + return null; + } + + /** + * Returns the result of interpretting the object as an instance of 'EClass Hierarchy'. + * + * This implementation returns null; + * returning a non-null result will terminate the switch. + * + * @param object the target of the switch. + * @return the result of interpretting the object as an instance of 'EClass Hierarchy'. + * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject) + * @generated + */ + public Object caseEClassHierarchy(EClassHierarchy object) { + return null; + } + + /** + * Returns the result of interpretting the object as an instance of 'EInterface Hierarchy'. + * + * This implementation returns null; + * returning a non-null result will terminate the switch. + * + * @param object the target of the switch. + * @return the result of interpretting the object as an instance of 'EInterface Hierarchy'. + * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject) + * @generated + */ + public Object caseEInterfaceHierarchy(EInterfaceHierarchy object) { + return null; + } + + /** + * Returns the result of interpretting the object as an instance of 'EType Hierarchy'. + * + * This implementation returns null; + * returning a non-null result will terminate the switch. + * + * @param object the target of the switch. + * @return the result of interpretting the object as an instance of 'EType Hierarchy'. + * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject) + * @generated + */ + public Object caseETypeHierarchy(ETypeHierarchy object) { + return null; + } + + /** + * Returns the result of interpretting the object as an instance of 'EObject With Container Id'. + * + * This implementation returns null; + * returning a non-null result will terminate the switch. + * + * @param object the target of the switch. + * @return the result of interpretting the object as an instance of 'EObject With Container Id'. + * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject) + * @generated + */ + public Object caseEObjectWithContainerId(EObjectWithContainerId object) { + return null; + } + + /** + * Returns the result of interpretting the object as an instance of 'EGraph'. + * + * This implementation returns null; + * returning a non-null result will terminate the switch. + * + * @param object the target of the switch. + * @return the result of interpretting the object as an instance of 'EGraph'. + * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject) + * @generated + */ + public Object caseEGraph(EGraph object) { + return null; + } + + /** + * Returns the result of interpretting the object as an instance of 'ETree'. + * + * This implementation returns null; + * returning a non-null result will terminate the switch. + * + * @param object the target of the switch. + * @return the result of interpretting the object as an instance of 'ETree'. + * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject) + * @generated + */ + public Object caseETree(ETree object) { + return null; + } + + /** + * Returns the result of interpretting the object as an instance of 'EObject'. + * + * This implementation returns null; + * returning a non-null result will terminate the switch, but this is the last case anyway. + * + * @param object the target of the switch. + * @return the result of interpretting the object as an instance of 'EObject'. + * @see #doSwitch(org.eclipse.emf.ecore.EObject) + * @generated + */ + public Object defaultCase(EObject object) { + return null; + } + +} //JavaSwitch diff --git a/com.ibm.wala.emf/src/com/ibm/wala/ecore/perf/EPhaseTiming.java b/com.ibm.wala.emf/src/com/ibm/wala/ecore/perf/EPhaseTiming.java new file mode 100644 index 000000000..56ced45a4 --- /dev/null +++ b/com.ibm.wala.emf/src/com/ibm/wala/ecore/perf/EPhaseTiming.java @@ -0,0 +1,108 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.perf; + +import org.eclipse.emf.ecore.EObject; + +/** + * + * A representation of the model object 'EPhase Timing'. + * + * + *

                              + * The following features are supported: + *

                                + *
                              • {@link com.ibm.wala.ecore.perf.EPhaseTiming#getName Name}
                              • + *
                              • {@link com.ibm.wala.ecore.perf.EPhaseTiming#getMillis Millis}
                              • + *
                              • {@link com.ibm.wala.ecore.perf.EPhaseTiming#getOrder Order}
                              • + *
                              + *

                              + * + * @see com.ibm.wala.ecore.perf.PerfPackage#getEPhaseTiming() + * @model + * @generated + */ +public interface EPhaseTiming extends EObject { + /** + * Returns the value of the 'Name' attribute. + * + *

                              + * If the meaning of the 'Name' attribute isn't clear, + * there really should be more of a description here... + *

                              + * + * @return the value of the 'Name' attribute. + * @see #setName(String) + * @see com.ibm.wala.ecore.perf.PerfPackage#getEPhaseTiming_Name() + * @model required="true" + * @generated + */ + String getName(); + + /** + * Sets the value of the '{@link com.ibm.wala.ecore.perf.EPhaseTiming#getName Name}' attribute. + * + * + * @param value the new value of the 'Name' attribute. + * @see #getName() + * @generated + */ + void setName(String value); + + /** + * Returns the value of the 'Millis' attribute. + * + *

                              + * If the meaning of the 'Millis' attribute isn't clear, + * there really should be more of a description here... + *

                              + * + * @return the value of the 'Millis' attribute. + * @see #setMillis(long) + * @see com.ibm.wala.ecore.perf.PerfPackage#getEPhaseTiming_Millis() + * @model required="true" + * @generated + */ + long getMillis(); + + /** + * Sets the value of the '{@link com.ibm.wala.ecore.perf.EPhaseTiming#getMillis Millis}' attribute. + * + * + * @param value the new value of the 'Millis' attribute. + * @see #getMillis() + * @generated + */ + void setMillis(long value); + + /** + * Returns the value of the 'Order' attribute. + * + *

                              + * If the meaning of the 'Order' attribute isn't clear, + * there really should be more of a description here... + *

                              + * + * @return the value of the 'Order' attribute. + * @see #setOrder(int) + * @see com.ibm.wala.ecore.perf.PerfPackage#getEPhaseTiming_Order() + * @model required="true" + * @generated + */ + int getOrder(); + + /** + * Sets the value of the '{@link com.ibm.wala.ecore.perf.EPhaseTiming#getOrder Order}' attribute. + * + * + * @param value the new value of the 'Order' attribute. + * @see #getOrder() + * @generated + */ + void setOrder(int value); + +} // EPhaseTiming \ No newline at end of file diff --git a/com.ibm.wala.emf/src/com/ibm/wala/ecore/perf/PerfFactory.java b/com.ibm.wala.emf/src/com/ibm/wala/ecore/perf/PerfFactory.java new file mode 100644 index 000000000..ae0109ef6 --- /dev/null +++ b/com.ibm.wala.emf/src/com/ibm/wala/ecore/perf/PerfFactory.java @@ -0,0 +1,46 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.perf; + +import org.eclipse.emf.ecore.EFactory; + +/** + * + * The Factory for the model. + * It provides a create method for each non-abstract class of the model. + * + * @see com.ibm.wala.ecore.perf.PerfPackage + * @generated + */ +public interface PerfFactory extends EFactory { + /** + * The singleton instance of the factory. + * + * + * @generated + */ + PerfFactory eINSTANCE = com.ibm.wala.ecore.perf.impl.PerfFactoryImpl.init(); + + /** + * Returns a new object of class 'EPhase Timing'. + * + * + * @return a new object of class 'EPhase Timing'. + * @generated + */ + EPhaseTiming createEPhaseTiming(); + + /** + * Returns the package supported by this factory. + * + * + * @return the package supported by this factory. + * @generated + */ + PerfPackage getPerfPackage(); + +} //PerfFactory diff --git a/com.ibm.wala.emf/src/com/ibm/wala/ecore/perf/PerfPackage.java b/com.ibm.wala.emf/src/com/ibm/wala/ecore/perf/PerfPackage.java new file mode 100644 index 000000000..9fa95ddb0 --- /dev/null +++ b/com.ibm.wala.emf/src/com/ibm/wala/ecore/perf/PerfPackage.java @@ -0,0 +1,209 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.perf; + +import org.eclipse.emf.ecore.EAttribute; +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EPackage; + +/** + * + * The Package for the model. + * It contains accessors for the meta objects to represent + *
                                + *
                              • each class,
                              • + *
                              • each feature of each class,
                              • + *
                              • each enum,
                              • + *
                              • and each data type
                              • + *
                              + * + * @see com.ibm.wala.ecore.perf.PerfFactory + * @model kind="package" + * @generated + */ +public interface PerfPackage extends EPackage { + /** + * The package name. + * + * + * @generated + */ + String eNAME = "perf"; + + /** + * The package namespace URI. + * + * + * @generated + */ + String eNS_URI = "http:///com/ibm/wala/wala.ecore.perf"; + + /** + * The package namespace name. + * + * + * @generated + */ + String eNS_PREFIX = "com.ibm.wala.perf"; + + /** + * The singleton instance of the package. + * + * + * @generated + */ + PerfPackage eINSTANCE = com.ibm.wala.ecore.perf.impl.PerfPackageImpl.init(); + + /** + * The meta object id for the '{@link com.ibm.wala.ecore.perf.impl.EPhaseTimingImpl EPhase Timing}' class. + * + * + * @see com.ibm.wala.ecore.perf.impl.EPhaseTimingImpl + * @see com.ibm.wala.ecore.perf.impl.PerfPackageImpl#getEPhaseTiming() + * @generated + */ + int EPHASE_TIMING = 0; + + /** + * The feature id for the 'Name' attribute. + * + * + * @generated + * @ordered + */ + int EPHASE_TIMING__NAME = 0; + + /** + * The feature id for the 'Millis' attribute. + * + * + * @generated + * @ordered + */ + int EPHASE_TIMING__MILLIS = 1; + + /** + * The feature id for the 'Order' attribute. + * + * + * @generated + * @ordered + */ + int EPHASE_TIMING__ORDER = 2; + + /** + * The number of structural features of the 'EPhase Timing' class. + * + * + * @generated + * @ordered + */ + int EPHASE_TIMING_FEATURE_COUNT = 3; + + + /** + * Returns the meta object for class '{@link com.ibm.wala.ecore.perf.EPhaseTiming EPhase Timing}'. + * + * + * @return the meta object for class 'EPhase Timing'. + * @see com.ibm.wala.ecore.perf.EPhaseTiming + * @generated + */ + EClass getEPhaseTiming(); + + /** + * Returns the meta object for the attribute '{@link com.ibm.wala.ecore.perf.EPhaseTiming#getName Name}'. + * + * + * @return the meta object for the attribute 'Name'. + * @see com.ibm.wala.ecore.perf.EPhaseTiming#getName() + * @see #getEPhaseTiming() + * @generated + */ + EAttribute getEPhaseTiming_Name(); + + /** + * Returns the meta object for the attribute '{@link com.ibm.wala.ecore.perf.EPhaseTiming#getMillis Millis}'. + * + * + * @return the meta object for the attribute 'Millis'. + * @see com.ibm.wala.ecore.perf.EPhaseTiming#getMillis() + * @see #getEPhaseTiming() + * @generated + */ + EAttribute getEPhaseTiming_Millis(); + + /** + * Returns the meta object for the attribute '{@link com.ibm.wala.ecore.perf.EPhaseTiming#getOrder Order}'. + * + * + * @return the meta object for the attribute 'Order'. + * @see com.ibm.wala.ecore.perf.EPhaseTiming#getOrder() + * @see #getEPhaseTiming() + * @generated + */ + EAttribute getEPhaseTiming_Order(); + + /** + * Returns the factory that creates the instances of the model. + * + * + * @return the factory that creates the instances of the model. + * @generated + */ + PerfFactory getPerfFactory(); + + /** + * + * Defines literals for the meta objects that represent + *
                                + *
                              • each class,
                              • + *
                              • each feature of each class,
                              • + *
                              • each enum,
                              • + *
                              • and each data type
                              • + *
                              + * + * @generated + */ + interface Literals { + /** + * The meta object literal for the '{@link com.ibm.wala.ecore.perf.impl.EPhaseTimingImpl EPhase Timing}' class. + * + * + * @see com.ibm.wala.ecore.perf.impl.EPhaseTimingImpl + * @see com.ibm.wala.ecore.perf.impl.PerfPackageImpl#getEPhaseTiming() + * @generated + */ + EClass EPHASE_TIMING = eINSTANCE.getEPhaseTiming(); + + /** + * The meta object literal for the 'Name' attribute feature. + * + * + * @generated + */ + EAttribute EPHASE_TIMING__NAME = eINSTANCE.getEPhaseTiming_Name(); + + /** + * The meta object literal for the 'Millis' attribute feature. + * + * + * @generated + */ + EAttribute EPHASE_TIMING__MILLIS = eINSTANCE.getEPhaseTiming_Millis(); + + /** + * The meta object literal for the 'Order' attribute feature. + * + * + * @generated + */ + EAttribute EPHASE_TIMING__ORDER = eINSTANCE.getEPhaseTiming_Order(); + + } + +} //PerfPackage diff --git a/com.ibm.wala.emf/src/com/ibm/wala/ecore/perf/impl/EPhaseTimingImpl.java b/com.ibm.wala.emf/src/com/ibm/wala/ecore/perf/impl/EPhaseTimingImpl.java new file mode 100644 index 000000000..4ea219af6 --- /dev/null +++ b/com.ibm.wala.emf/src/com/ibm/wala/ecore/perf/impl/EPhaseTimingImpl.java @@ -0,0 +1,269 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.perf.impl; + +import com.ibm.wala.ecore.perf.EPhaseTiming; +import com.ibm.wala.ecore.perf.PerfPackage; + +import org.eclipse.emf.common.notify.Notification; + +import org.eclipse.emf.ecore.EClass; + +import org.eclipse.emf.ecore.impl.ENotificationImpl; +import org.eclipse.emf.ecore.impl.EObjectImpl; + +/** + * + * An implementation of the model object 'EPhase Timing'. + * + *

                              + * The following features are implemented: + *

                                + *
                              • {@link com.ibm.wala.ecore.perf.impl.EPhaseTimingImpl#getName Name}
                              • + *
                              • {@link com.ibm.wala.ecore.perf.impl.EPhaseTimingImpl#getMillis Millis}
                              • + *
                              • {@link com.ibm.wala.ecore.perf.impl.EPhaseTimingImpl#getOrder Order}
                              • + *
                              + *

                              + * + * @generated + */ +public class EPhaseTimingImpl extends EObjectImpl implements EPhaseTiming { + /** + * The default value of the '{@link #getName() Name}' attribute. + * + * + * @see #getName() + * @generated + * @ordered + */ + protected static final String NAME_EDEFAULT = null; + + /** + * The cached value of the '{@link #getName() Name}' attribute. + * + * + * @see #getName() + * @generated + * @ordered + */ + protected String name = NAME_EDEFAULT; + + /** + * The default value of the '{@link #getMillis() Millis}' attribute. + * + * + * @see #getMillis() + * @generated + * @ordered + */ + protected static final long MILLIS_EDEFAULT = 0L; + + /** + * The cached value of the '{@link #getMillis() Millis}' attribute. + * + * + * @see #getMillis() + * @generated + * @ordered + */ + protected long millis = MILLIS_EDEFAULT; + + /** + * The default value of the '{@link #getOrder() Order}' attribute. + * + * + * @see #getOrder() + * @generated + * @ordered + */ + protected static final int ORDER_EDEFAULT = 0; + + /** + * The cached value of the '{@link #getOrder() Order}' attribute. + * + * + * @see #getOrder() + * @generated + * @ordered + */ + protected int order = ORDER_EDEFAULT; + + /** + * + * + * @generated + */ + protected EPhaseTimingImpl() { + super(); + } + + /** + * + * + * @generated + */ + protected EClass eStaticClass() { + return PerfPackage.Literals.EPHASE_TIMING; + } + + /** + * + * + * @generated + */ + public String getName() { + return name; + } + + /** + * + * + * @generated + */ + public void setName(String newName) { + String oldName = name; + name = newName; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, PerfPackage.EPHASE_TIMING__NAME, oldName, name)); + } + + /** + * + * + * @generated + */ + public long getMillis() { + return millis; + } + + /** + * + * + * @generated + */ + public void setMillis(long newMillis) { + long oldMillis = millis; + millis = newMillis; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, PerfPackage.EPHASE_TIMING__MILLIS, oldMillis, millis)); + } + + /** + * + * + * @generated + */ + public int getOrder() { + return order; + } + + /** + * + * + * @generated + */ + public void setOrder(int newOrder) { + int oldOrder = order; + order = newOrder; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, PerfPackage.EPHASE_TIMING__ORDER, oldOrder, order)); + } + + /** + * + * + * @generated + */ + public Object eGet(int featureID, boolean resolve, boolean coreType) { + switch (featureID) { + case PerfPackage.EPHASE_TIMING__NAME: + return getName(); + case PerfPackage.EPHASE_TIMING__MILLIS: + return new Long(getMillis()); + case PerfPackage.EPHASE_TIMING__ORDER: + return new Integer(getOrder()); + } + return super.eGet(featureID, resolve, coreType); + } + + /** + * + * + * @generated + */ + public void eSet(int featureID, Object newValue) { + switch (featureID) { + case PerfPackage.EPHASE_TIMING__NAME: + setName((String)newValue); + return; + case PerfPackage.EPHASE_TIMING__MILLIS: + setMillis(((Long)newValue).longValue()); + return; + case PerfPackage.EPHASE_TIMING__ORDER: + setOrder(((Integer)newValue).intValue()); + return; + } + super.eSet(featureID, newValue); + } + + /** + * + * + * @generated + */ + public void eUnset(int featureID) { + switch (featureID) { + case PerfPackage.EPHASE_TIMING__NAME: + setName(NAME_EDEFAULT); + return; + case PerfPackage.EPHASE_TIMING__MILLIS: + setMillis(MILLIS_EDEFAULT); + return; + case PerfPackage.EPHASE_TIMING__ORDER: + setOrder(ORDER_EDEFAULT); + return; + } + super.eUnset(featureID); + } + + /** + * + * + * @generated + */ + public boolean eIsSet(int featureID) { + switch (featureID) { + case PerfPackage.EPHASE_TIMING__NAME: + return NAME_EDEFAULT == null ? name != null : !NAME_EDEFAULT.equals(name); + case PerfPackage.EPHASE_TIMING__MILLIS: + return millis != MILLIS_EDEFAULT; + case PerfPackage.EPHASE_TIMING__ORDER: + return order != ORDER_EDEFAULT; + } + return super.eIsSet(featureID); + } + + /** + * + * + * @generated + */ + public String toString() { + if (eIsProxy()) return super.toString(); + + StringBuffer result = new StringBuffer(super.toString()); + result.append(" (name: "); + result.append(name); + result.append(", millis: "); + result.append(millis); + result.append(", order: "); + result.append(order); + result.append(')'); + return result.toString(); + } + +} //EPhaseTimingImpl \ No newline at end of file diff --git a/com.ibm.wala.emf/src/com/ibm/wala/ecore/perf/impl/PerfFactoryImpl.java b/com.ibm.wala.emf/src/com/ibm/wala/ecore/perf/impl/PerfFactoryImpl.java new file mode 100644 index 000000000..f2ab9f7dd --- /dev/null +++ b/com.ibm.wala.emf/src/com/ibm/wala/ecore/perf/impl/PerfFactoryImpl.java @@ -0,0 +1,97 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.perf.impl; + +import com.ibm.wala.ecore.perf.*; + +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EPackage; + +import org.eclipse.emf.ecore.impl.EFactoryImpl; + +import org.eclipse.emf.ecore.plugin.EcorePlugin; + +/** + * + * An implementation of the model Factory. + * + * @generated + */ +public class PerfFactoryImpl extends EFactoryImpl implements PerfFactory { + /** + * Creates the default factory implementation. + * + * + * @generated + */ + public static PerfFactory init() { + try { + PerfFactory thePerfFactory = (PerfFactory)EPackage.Registry.INSTANCE.getEFactory("http:///com/ibm/wala/wala.ecore.perf"); + if (thePerfFactory != null) { + return thePerfFactory; + } + } + catch (Exception exception) { + EcorePlugin.INSTANCE.log(exception); + } + return new PerfFactoryImpl(); + } + + /** + * Creates an instance of the factory. + * + * + * @generated + */ + public PerfFactoryImpl() { + super(); + } + + /** + * + * + * @generated + */ + public EObject create(EClass eClass) { + switch (eClass.getClassifierID()) { + case PerfPackage.EPHASE_TIMING: return createEPhaseTiming(); + default: + throw new IllegalArgumentException("The class '" + eClass.getName() + "' is not a valid classifier"); + } + } + + /** + * + * + * @generated + */ + public EPhaseTiming createEPhaseTiming() { + EPhaseTimingImpl ePhaseTiming = new EPhaseTimingImpl(); + return ePhaseTiming; + } + + /** + * + * + * @generated + */ + public PerfPackage getPerfPackage() { + return (PerfPackage)getEPackage(); + } + + /** + * + * + * @deprecated + * @generated + */ + public static PerfPackage getPackage() { + return PerfPackage.eINSTANCE; + } + +} //PerfFactoryImpl diff --git a/com.ibm.wala.emf/src/com/ibm/wala/ecore/perf/impl/PerfPackageImpl.java b/com.ibm.wala.emf/src/com/ibm/wala/ecore/perf/impl/PerfPackageImpl.java new file mode 100644 index 000000000..df9913bd5 --- /dev/null +++ b/com.ibm.wala.emf/src/com/ibm/wala/ecore/perf/impl/PerfPackageImpl.java @@ -0,0 +1,264 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.perf.impl; + +import com.ibm.wala.ecore.common.CommonPackage; + +import com.ibm.wala.ecore.common.impl.CommonPackageImpl; + +import com.ibm.wala.ecore.graph.GraphPackage; + +import com.ibm.wala.ecore.graph.impl.GraphPackageImpl; + +import com.ibm.wala.ecore.j2ee.scope.J2EEScopePackage; + +import com.ibm.wala.ecore.j2ee.scope.impl.J2EEScopePackageImpl; + +import com.ibm.wala.ecore.java.JavaPackage; + +import com.ibm.wala.ecore.java.callGraph.CallGraphPackage; + +import com.ibm.wala.ecore.java.callGraph.impl.CallGraphPackageImpl; + +import com.ibm.wala.ecore.java.impl.JavaPackageImpl; + +import com.ibm.wala.ecore.java.pointerAnalysis.PointerAnalysisPackage; + +import com.ibm.wala.ecore.java.pointerAnalysis.impl.PointerAnalysisPackageImpl; + +import com.ibm.wala.ecore.java.scope.JavaScopePackage; + +import com.ibm.wala.ecore.java.scope.impl.JavaScopePackageImpl; + +import com.ibm.wala.ecore.perf.EPhaseTiming; +import com.ibm.wala.ecore.perf.PerfFactory; +import com.ibm.wala.ecore.perf.PerfPackage; + +import com.ibm.wala.ecore.regex.RegexPackage; + +import com.ibm.wala.ecore.regex.impl.RegexPackageImpl; + +import org.eclipse.emf.ecore.EAttribute; +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EPackage; + +import org.eclipse.emf.ecore.impl.EPackageImpl; + +/** + * + * An implementation of the model Package. + * + * @generated + */ +public class PerfPackageImpl extends EPackageImpl implements PerfPackage { + /** + * + * + * @generated + */ + private EClass ePhaseTimingEClass = null; + + /** + * Creates an instance of the model Package, registered with + * {@link org.eclipse.emf.ecore.EPackage.Registry EPackage.Registry} by the package + * package URI value. + *

                              Note: the correct way to create the package is via the static + * factory method {@link #init init()}, which also performs + * initialization of the package, or returns the registered package, + * if one already exists. + * + * + * @see org.eclipse.emf.ecore.EPackage.Registry + * @see com.ibm.wala.ecore.perf.PerfPackage#eNS_URI + * @see #init() + * @generated + */ + private PerfPackageImpl() { + super(eNS_URI, PerfFactory.eINSTANCE); + } + + /** + * + * + * @generated + */ + private static boolean isInited = false; + + /** + * Creates, registers, and initializes the Package for this + * model, and for any others upon which it depends. Simple + * dependencies are satisfied by calling this method on all + * dependent packages before doing anything else. This method drives + * initialization for interdependent packages directly, in parallel + * with this package, itself. + *

                              Of this package and its interdependencies, all packages which + * have not yet been registered by their URI values are first created + * and registered. The packages are then initialized in two steps: + * meta-model objects for all of the packages are created before any + * are initialized, since one package's meta-model objects may refer to + * those of another. + *

                              Invocation of this method will not affect any packages that have + * already been initialized. + * + * + * @see #eNS_URI + * @see #createPackageContents() + * @see #initializePackageContents() + * @generated + */ + public static PerfPackage init() { + if (isInited) return (PerfPackage)EPackage.Registry.INSTANCE.getEPackage(PerfPackage.eNS_URI); + + // Obtain or create and register package + PerfPackageImpl thePerfPackage = (PerfPackageImpl)(EPackage.Registry.INSTANCE.getEPackage(eNS_URI) instanceof PerfPackageImpl ? EPackage.Registry.INSTANCE.getEPackage(eNS_URI) : new PerfPackageImpl()); + + isInited = true; + + // Obtain or create and register interdependencies + GraphPackageImpl theGraphPackage = (GraphPackageImpl)(EPackage.Registry.INSTANCE.getEPackage(GraphPackage.eNS_URI) instanceof GraphPackageImpl ? EPackage.Registry.INSTANCE.getEPackage(GraphPackage.eNS_URI) : GraphPackage.eINSTANCE); + CommonPackageImpl theCommonPackage = (CommonPackageImpl)(EPackage.Registry.INSTANCE.getEPackage(CommonPackage.eNS_URI) instanceof CommonPackageImpl ? EPackage.Registry.INSTANCE.getEPackage(CommonPackage.eNS_URI) : CommonPackage.eINSTANCE); + RegexPackageImpl theRegexPackage = (RegexPackageImpl)(EPackage.Registry.INSTANCE.getEPackage(RegexPackage.eNS_URI) instanceof RegexPackageImpl ? EPackage.Registry.INSTANCE.getEPackage(RegexPackage.eNS_URI) : RegexPackage.eINSTANCE); + JavaPackageImpl theJavaPackage = (JavaPackageImpl)(EPackage.Registry.INSTANCE.getEPackage(JavaPackage.eNS_URI) instanceof JavaPackageImpl ? EPackage.Registry.INSTANCE.getEPackage(JavaPackage.eNS_URI) : JavaPackage.eINSTANCE); + CallGraphPackageImpl theCallGraphPackage = (CallGraphPackageImpl)(EPackage.Registry.INSTANCE.getEPackage(CallGraphPackage.eNS_URI) instanceof CallGraphPackageImpl ? EPackage.Registry.INSTANCE.getEPackage(CallGraphPackage.eNS_URI) : CallGraphPackage.eINSTANCE); + PointerAnalysisPackageImpl thePointerAnalysisPackage = (PointerAnalysisPackageImpl)(EPackage.Registry.INSTANCE.getEPackage(PointerAnalysisPackage.eNS_URI) instanceof PointerAnalysisPackageImpl ? EPackage.Registry.INSTANCE.getEPackage(PointerAnalysisPackage.eNS_URI) : PointerAnalysisPackage.eINSTANCE); + JavaScopePackageImpl theJavaScopePackage = (JavaScopePackageImpl)(EPackage.Registry.INSTANCE.getEPackage(JavaScopePackage.eNS_URI) instanceof JavaScopePackageImpl ? EPackage.Registry.INSTANCE.getEPackage(JavaScopePackage.eNS_URI) : JavaScopePackage.eINSTANCE); + J2EEScopePackageImpl theJ2EEScopePackage = (J2EEScopePackageImpl)(EPackage.Registry.INSTANCE.getEPackage(J2EEScopePackage.eNS_URI) instanceof J2EEScopePackageImpl ? EPackage.Registry.INSTANCE.getEPackage(J2EEScopePackage.eNS_URI) : J2EEScopePackage.eINSTANCE); + + // Create package meta-data objects + thePerfPackage.createPackageContents(); + theGraphPackage.createPackageContents(); + theCommonPackage.createPackageContents(); + theRegexPackage.createPackageContents(); + theJavaPackage.createPackageContents(); + theCallGraphPackage.createPackageContents(); + thePointerAnalysisPackage.createPackageContents(); + theJavaScopePackage.createPackageContents(); + theJ2EEScopePackage.createPackageContents(); + + // Initialize created meta-data + thePerfPackage.initializePackageContents(); + theGraphPackage.initializePackageContents(); + theCommonPackage.initializePackageContents(); + theRegexPackage.initializePackageContents(); + theJavaPackage.initializePackageContents(); + theCallGraphPackage.initializePackageContents(); + thePointerAnalysisPackage.initializePackageContents(); + theJavaScopePackage.initializePackageContents(); + theJ2EEScopePackage.initializePackageContents(); + + // Mark meta-data to indicate it can't be changed + thePerfPackage.freeze(); + + return thePerfPackage; + } + + /** + * + * + * @generated + */ + public EClass getEPhaseTiming() { + return ePhaseTimingEClass; + } + + /** + * + * + * @generated + */ + public EAttribute getEPhaseTiming_Name() { + return (EAttribute)ePhaseTimingEClass.getEStructuralFeatures().get(0); + } + + /** + * + * + * @generated + */ + public EAttribute getEPhaseTiming_Millis() { + return (EAttribute)ePhaseTimingEClass.getEStructuralFeatures().get(1); + } + + /** + * + * + * @generated + */ + public EAttribute getEPhaseTiming_Order() { + return (EAttribute)ePhaseTimingEClass.getEStructuralFeatures().get(2); + } + + /** + * + * + * @generated + */ + public PerfFactory getPerfFactory() { + return (PerfFactory)getEFactoryInstance(); + } + + /** + * + * + * @generated + */ + private boolean isCreated = false; + + /** + * Creates the meta-model objects for the package. This method is + * guarded to have no affect on any invocation but its first. + * + * + * @generated + */ + public void createPackageContents() { + if (isCreated) return; + isCreated = true; + + // Create classes and their features + ePhaseTimingEClass = createEClass(EPHASE_TIMING); + createEAttribute(ePhaseTimingEClass, EPHASE_TIMING__NAME); + createEAttribute(ePhaseTimingEClass, EPHASE_TIMING__MILLIS); + createEAttribute(ePhaseTimingEClass, EPHASE_TIMING__ORDER); + } + + /** + * + * + * @generated + */ + private boolean isInitialized = false; + + /** + * Complete the initialization of the package and its meta-model. This + * method is guarded to have no affect on any invocation but its first. + * + * + * @generated + */ + public void initializePackageContents() { + if (isInitialized) return; + isInitialized = true; + + // Initialize package + setName(eNAME); + setNsPrefix(eNS_PREFIX); + setNsURI(eNS_URI); + + // Add supertypes to classes + + // Initialize classes and features; add operations and parameters + initEClass(ePhaseTimingEClass, EPhaseTiming.class, "EPhaseTiming", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); + initEAttribute(getEPhaseTiming_Name(), ecorePackage.getEString(), "name", null, 1, 1, EPhaseTiming.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); + initEAttribute(getEPhaseTiming_Millis(), ecorePackage.getELong(), "millis", null, 1, 1, EPhaseTiming.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); + initEAttribute(getEPhaseTiming_Order(), ecorePackage.getEInt(), "order", null, 1, 1, EPhaseTiming.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); + + // Create resource + createResource(eNS_URI); + } + +} //PerfPackageImpl diff --git a/com.ibm.wala.emf/src/com/ibm/wala/ecore/perf/util/PerfAdapterFactory.java b/com.ibm.wala.emf/src/com/ibm/wala/ecore/perf/util/PerfAdapterFactory.java new file mode 100644 index 000000000..b2f08d451 --- /dev/null +++ b/com.ibm.wala.emf/src/com/ibm/wala/ecore/perf/util/PerfAdapterFactory.java @@ -0,0 +1,120 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.perf.util; + +import com.ibm.wala.ecore.perf.*; + +import org.eclipse.emf.common.notify.Adapter; +import org.eclipse.emf.common.notify.Notifier; + +import org.eclipse.emf.common.notify.impl.AdapterFactoryImpl; + +import org.eclipse.emf.ecore.EObject; + +/** + * + * The Adapter Factory for the model. + * It provides an adapter createXXX method for each class of the model. + * + * @see com.ibm.wala.ecore.perf.PerfPackage + * @generated + */ +public class PerfAdapterFactory extends AdapterFactoryImpl { + /** + * The cached model package. + * + * + * @generated + */ + protected static PerfPackage modelPackage; + + /** + * Creates an instance of the adapter factory. + * + * + * @generated + */ + public PerfAdapterFactory() { + if (modelPackage == null) { + modelPackage = PerfPackage.eINSTANCE; + } + } + + /** + * Returns whether this factory is applicable for the type of the object. + * + * This implementation returns true if the object is either the model's package or is an instance object of the model. + * + * @return whether this factory is applicable for the type of the object. + * @generated + */ + public boolean isFactoryForType(Object object) { + if (object == modelPackage) { + return true; + } + if (object instanceof EObject) { + return ((EObject)object).eClass().getEPackage() == modelPackage; + } + return false; + } + + /** + * The switch the delegates to the createXXX methods. + * + * + * @generated + */ + protected PerfSwitch modelSwitch = + new PerfSwitch() { + public Object caseEPhaseTiming(EPhaseTiming object) { + return createEPhaseTimingAdapter(); + } + public Object defaultCase(EObject object) { + return createEObjectAdapter(); + } + }; + + /** + * Creates an adapter for the target. + * + * + * @param target the object to adapt. + * @return the adapter for the target. + * @generated + */ + public Adapter createAdapter(Notifier target) { + return (Adapter)modelSwitch.doSwitch((EObject)target); + } + + + /** + * Creates a new adapter for an object of class '{@link com.ibm.wala.ecore.perf.EPhaseTiming EPhase Timing}'. + * + * This default implementation returns null so that we can easily ignore cases; + * it's useful to ignore a case when inheritance will catch all the cases anyway. + * + * @return the new adapter. + * @see com.ibm.wala.ecore.perf.EPhaseTiming + * @generated + */ + public Adapter createEPhaseTimingAdapter() { + return null; + } + + /** + * Creates a new adapter for the default case. + * + * This default implementation returns null. + * + * @return the new adapter. + * @generated + */ + public Adapter createEObjectAdapter() { + return null; + } + +} //PerfAdapterFactory diff --git a/com.ibm.wala.emf/src/com/ibm/wala/ecore/perf/util/PerfSwitch.java b/com.ibm.wala.emf/src/com/ibm/wala/ecore/perf/util/PerfSwitch.java new file mode 100644 index 000000000..54bc90f21 --- /dev/null +++ b/com.ibm.wala.emf/src/com/ibm/wala/ecore/perf/util/PerfSwitch.java @@ -0,0 +1,130 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.perf.util; + +import com.ibm.wala.ecore.perf.*; + +import java.util.List; + +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EObject; + +/** + * + * The Switch for the model's inheritance hierarchy. + * It supports the call {@link #doSwitch(EObject) doSwitch(object)} + * to invoke the caseXXX method for each class of the model, + * starting with the actual class of the object + * and proceeding up the inheritance hierarchy + * until a non-null result is returned, + * which is the result of the switch. + * + * @see com.ibm.wala.ecore.perf.PerfPackage + * @generated + */ +public class PerfSwitch { + /** + * The cached model package + * + * + * @generated + */ + protected static PerfPackage modelPackage; + + /** + * Creates an instance of the switch. + * + * + * @generated + */ + public PerfSwitch() { + if (modelPackage == null) { + modelPackage = PerfPackage.eINSTANCE; + } + } + + /** + * Calls caseXXX for each class of the model until one returns a non null result; it yields that result. + * + * + * @return the first non-null result returned by a caseXXX call. + * @generated + */ + public Object doSwitch(EObject theEObject) { + return doSwitch(theEObject.eClass(), theEObject); + } + + /** + * Calls caseXXX for each class of the model until one returns a non null result; it yields that result. + * + * + * @return the first non-null result returned by a caseXXX call. + * @generated + */ + protected Object doSwitch(EClass theEClass, EObject theEObject) { + if (theEClass.eContainer() == modelPackage) { + return doSwitch(theEClass.getClassifierID(), theEObject); + } + else { + List eSuperTypes = theEClass.getESuperTypes(); + return + eSuperTypes.isEmpty() ? + defaultCase(theEObject) : + doSwitch((EClass)eSuperTypes.get(0), theEObject); + } + } + + /** + * Calls caseXXX for each class of the model until one returns a non null result; it yields that result. + * + * + * @return the first non-null result returned by a caseXXX call. + * @generated + */ + protected Object doSwitch(int classifierID, EObject theEObject) { + switch (classifierID) { + case PerfPackage.EPHASE_TIMING: { + EPhaseTiming ePhaseTiming = (EPhaseTiming)theEObject; + Object result = caseEPhaseTiming(ePhaseTiming); + if (result == null) result = defaultCase(theEObject); + return result; + } + default: return defaultCase(theEObject); + } + } + + /** + * Returns the result of interpretting the object as an instance of 'EPhase Timing'. + * + * This implementation returns null; + * returning a non-null result will terminate the switch. + * + * @param object the target of the switch. + * @return the result of interpretting the object as an instance of 'EPhase Timing'. + * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject) + * @generated + */ + public Object caseEPhaseTiming(EPhaseTiming object) { + return null; + } + + /** + * Returns the result of interpretting the object as an instance of 'EObject'. + * + * This implementation returns null; + * returning a non-null result will terminate the switch, but this is the last case anyway. + * + * @param object the target of the switch. + * @return the result of interpretting the object as an instance of 'EObject'. + * @see #doSwitch(org.eclipse.emf.ecore.EObject) + * @generated + */ + public Object defaultCase(EObject object) { + return null; + } + +} //PerfSwitch diff --git a/com.ibm.wala.emf/src/com/ibm/wala/ecore/regex/EPattern.java b/com.ibm.wala.emf/src/com/ibm/wala/ecore/regex/EPattern.java new file mode 100644 index 000000000..feb8e20dd --- /dev/null +++ b/com.ibm.wala.emf/src/com/ibm/wala/ecore/regex/EPattern.java @@ -0,0 +1,54 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.regex; + +import org.eclipse.emf.ecore.EObject; + +/** + * + * A representation of the model object 'EPattern'. + * + * + *

                              + * The following features are supported: + *

                                + *
                              • {@link com.ibm.wala.ecore.regex.EPattern#getPattern Pattern}
                              • + *
                              + *

                              + * + * @see com.ibm.wala.ecore.regex.RegexPackage#getEPattern() + * @model + * @generated + */ +public interface EPattern extends EObject { + /** + * Returns the value of the 'Pattern' attribute. + * + *

                              + * If the meaning of the 'Pattern' attribute isn't clear, + * there really should be more of a description here... + *

                              + * + * @return the value of the 'Pattern' attribute. + * @see #setPattern(String) + * @see com.ibm.wala.ecore.regex.RegexPackage#getEPattern_Pattern() + * @model required="true" + * @generated + */ + String getPattern(); + + /** + * Sets the value of the '{@link com.ibm.wala.ecore.regex.EPattern#getPattern Pattern}' attribute. + * + * + * @param value the new value of the 'Pattern' attribute. + * @see #getPattern() + * @generated + */ + void setPattern(String value); + +} // EPattern \ No newline at end of file diff --git a/com.ibm.wala.emf/src/com/ibm/wala/ecore/regex/RegexFactory.java b/com.ibm.wala.emf/src/com/ibm/wala/ecore/regex/RegexFactory.java new file mode 100644 index 000000000..b71d81439 --- /dev/null +++ b/com.ibm.wala.emf/src/com/ibm/wala/ecore/regex/RegexFactory.java @@ -0,0 +1,46 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.regex; + +import org.eclipse.emf.ecore.EFactory; + +/** + * + * The Factory for the model. + * It provides a create method for each non-abstract class of the model. + * + * @see com.ibm.wala.ecore.regex.RegexPackage + * @generated + */ +public interface RegexFactory extends EFactory { + /** + * The singleton instance of the factory. + * + * + * @generated + */ + RegexFactory eINSTANCE = com.ibm.wala.ecore.regex.impl.RegexFactoryImpl.init(); + + /** + * Returns a new object of class 'EPattern'. + * + * + * @return a new object of class 'EPattern'. + * @generated + */ + EPattern createEPattern(); + + /** + * Returns the package supported by this factory. + * + * + * @return the package supported by this factory. + * @generated + */ + RegexPackage getRegexPackage(); + +} //RegexFactory diff --git a/com.ibm.wala.emf/src/com/ibm/wala/ecore/regex/RegexPackage.java b/com.ibm.wala.emf/src/com/ibm/wala/ecore/regex/RegexPackage.java new file mode 100644 index 000000000..7e6d30272 --- /dev/null +++ b/com.ibm.wala.emf/src/com/ibm/wala/ecore/regex/RegexPackage.java @@ -0,0 +1,153 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.regex; + +import org.eclipse.emf.ecore.EAttribute; +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EPackage; + +/** + * + * The Package for the model. + * It contains accessors for the meta objects to represent + *
                                + *
                              • each class,
                              • + *
                              • each feature of each class,
                              • + *
                              • each enum,
                              • + *
                              • and each data type
                              • + *
                              + * + * @see com.ibm.wala.ecore.regex.RegexFactory + * @model kind="package" + * @generated + */ +public interface RegexPackage extends EPackage { + /** + * The package name. + * + * + * @generated + */ + String eNAME = "regex"; + + /** + * The package namespace URI. + * + * + * @generated + */ + String eNS_URI = "http:///com/ibm/wala/wala.ecore.regex"; + + /** + * The package namespace name. + * + * + * @generated + */ + String eNS_PREFIX = "com.ibm.wala.regex"; + + /** + * The singleton instance of the package. + * + * + * @generated + */ + RegexPackage eINSTANCE = com.ibm.wala.ecore.regex.impl.RegexPackageImpl.init(); + + /** + * The meta object id for the '{@link com.ibm.wala.ecore.regex.impl.EPatternImpl EPattern}' class. + * + * + * @see com.ibm.wala.ecore.regex.impl.EPatternImpl + * @see com.ibm.wala.ecore.regex.impl.RegexPackageImpl#getEPattern() + * @generated + */ + int EPATTERN = 0; + + /** + * The feature id for the 'Pattern' attribute. + * + * + * @generated + * @ordered + */ + int EPATTERN__PATTERN = 0; + + /** + * The number of structural features of the 'EPattern' class. + * + * + * @generated + * @ordered + */ + int EPATTERN_FEATURE_COUNT = 1; + + + /** + * Returns the meta object for class '{@link com.ibm.wala.ecore.regex.EPattern EPattern}'. + * + * + * @return the meta object for class 'EPattern'. + * @see com.ibm.wala.ecore.regex.EPattern + * @generated + */ + EClass getEPattern(); + + /** + * Returns the meta object for the attribute '{@link com.ibm.wala.ecore.regex.EPattern#getPattern Pattern}'. + * + * + * @return the meta object for the attribute 'Pattern'. + * @see com.ibm.wala.ecore.regex.EPattern#getPattern() + * @see #getEPattern() + * @generated + */ + EAttribute getEPattern_Pattern(); + + /** + * Returns the factory that creates the instances of the model. + * + * + * @return the factory that creates the instances of the model. + * @generated + */ + RegexFactory getRegexFactory(); + + /** + * + * Defines literals for the meta objects that represent + *
                                + *
                              • each class,
                              • + *
                              • each feature of each class,
                              • + *
                              • each enum,
                              • + *
                              • and each data type
                              • + *
                              + * + * @generated + */ + interface Literals { + /** + * The meta object literal for the '{@link com.ibm.wala.ecore.regex.impl.EPatternImpl EPattern}' class. + * + * + * @see com.ibm.wala.ecore.regex.impl.EPatternImpl + * @see com.ibm.wala.ecore.regex.impl.RegexPackageImpl#getEPattern() + * @generated + */ + EClass EPATTERN = eINSTANCE.getEPattern(); + + /** + * The meta object literal for the 'Pattern' attribute feature. + * + * + * @generated + */ + EAttribute EPATTERN__PATTERN = eINSTANCE.getEPattern_Pattern(); + + } + +} //RegexPackage diff --git a/com.ibm.wala.emf/src/com/ibm/wala/ecore/regex/impl/EPatternImpl.java b/com.ibm.wala.emf/src/com/ibm/wala/ecore/regex/impl/EPatternImpl.java new file mode 100644 index 000000000..f351fd6ab --- /dev/null +++ b/com.ibm.wala.emf/src/com/ibm/wala/ecore/regex/impl/EPatternImpl.java @@ -0,0 +1,161 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.regex.impl; + +import com.ibm.wala.ecore.regex.EPattern; +import com.ibm.wala.ecore.regex.RegexPackage; + +import org.eclipse.emf.common.notify.Notification; + +import org.eclipse.emf.ecore.EClass; + +import org.eclipse.emf.ecore.impl.ENotificationImpl; +import org.eclipse.emf.ecore.impl.EObjectImpl; + +/** + * + * An implementation of the model object 'EPattern'. + * + *

                              + * The following features are implemented: + *

                                + *
                              • {@link com.ibm.wala.ecore.regex.impl.EPatternImpl#getPattern Pattern}
                              • + *
                              + *

                              + * + * @generated + */ +public class EPatternImpl extends EObjectImpl implements EPattern { + /** + * The default value of the '{@link #getPattern() Pattern}' attribute. + * + * + * @see #getPattern() + * @generated + * @ordered + */ + protected static final String PATTERN_EDEFAULT = null; + + /** + * The cached value of the '{@link #getPattern() Pattern}' attribute. + * + * + * @see #getPattern() + * @generated + * @ordered + */ + protected String pattern = PATTERN_EDEFAULT; + + /** + * + * + * @generated + */ + protected EPatternImpl() { + super(); + } + + /** + * + * + * @generated + */ + protected EClass eStaticClass() { + return RegexPackage.Literals.EPATTERN; + } + + /** + * + * + * @generated + */ + public String getPattern() { + return pattern; + } + + /** + * + * + * @generated + */ + public void setPattern(String newPattern) { + String oldPattern = pattern; + pattern = newPattern; + if (eNotificationRequired()) + eNotify(new ENotificationImpl(this, Notification.SET, RegexPackage.EPATTERN__PATTERN, oldPattern, pattern)); + } + + /** + * + * + * @generated + */ + public Object eGet(int featureID, boolean resolve, boolean coreType) { + switch (featureID) { + case RegexPackage.EPATTERN__PATTERN: + return getPattern(); + } + return super.eGet(featureID, resolve, coreType); + } + + /** + * + * + * @generated + */ + public void eSet(int featureID, Object newValue) { + switch (featureID) { + case RegexPackage.EPATTERN__PATTERN: + setPattern((String)newValue); + return; + } + super.eSet(featureID, newValue); + } + + /** + * + * + * @generated + */ + public void eUnset(int featureID) { + switch (featureID) { + case RegexPackage.EPATTERN__PATTERN: + setPattern(PATTERN_EDEFAULT); + return; + } + super.eUnset(featureID); + } + + /** + * + * + * @generated + */ + public boolean eIsSet(int featureID) { + switch (featureID) { + case RegexPackage.EPATTERN__PATTERN: + return PATTERN_EDEFAULT == null ? pattern != null : !PATTERN_EDEFAULT.equals(pattern); + } + return super.eIsSet(featureID); + } + + /** + * + * + * @generated + */ + public String toString() { + if (eIsProxy()) return super.toString(); + + StringBuffer result = new StringBuffer(super.toString()); + result.append(" (pattern: "); + result.append(pattern); + result.append(')'); + return result.toString(); + } + +} //EPatternImpl \ No newline at end of file diff --git a/com.ibm.wala.emf/src/com/ibm/wala/ecore/regex/impl/RegexFactoryImpl.java b/com.ibm.wala.emf/src/com/ibm/wala/ecore/regex/impl/RegexFactoryImpl.java new file mode 100644 index 000000000..1293b556c --- /dev/null +++ b/com.ibm.wala.emf/src/com/ibm/wala/ecore/regex/impl/RegexFactoryImpl.java @@ -0,0 +1,97 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.regex.impl; + +import com.ibm.wala.ecore.regex.*; + +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EPackage; + +import org.eclipse.emf.ecore.impl.EFactoryImpl; + +import org.eclipse.emf.ecore.plugin.EcorePlugin; + +/** + * + * An implementation of the model Factory. + * + * @generated + */ +public class RegexFactoryImpl extends EFactoryImpl implements RegexFactory { + /** + * Creates the default factory implementation. + * + * + * @generated + */ + public static RegexFactory init() { + try { + RegexFactory theRegexFactory = (RegexFactory)EPackage.Registry.INSTANCE.getEFactory("http:///com/ibm/wala/wala.ecore.regex"); + if (theRegexFactory != null) { + return theRegexFactory; + } + } + catch (Exception exception) { + EcorePlugin.INSTANCE.log(exception); + } + return new RegexFactoryImpl(); + } + + /** + * Creates an instance of the factory. + * + * + * @generated + */ + public RegexFactoryImpl() { + super(); + } + + /** + * + * + * @generated + */ + public EObject create(EClass eClass) { + switch (eClass.getClassifierID()) { + case RegexPackage.EPATTERN: return createEPattern(); + default: + throw new IllegalArgumentException("The class '" + eClass.getName() + "' is not a valid classifier"); + } + } + + /** + * + * + * @generated + */ + public EPattern createEPattern() { + EPatternImpl ePattern = new EPatternImpl(); + return ePattern; + } + + /** + * + * + * @generated + */ + public RegexPackage getRegexPackage() { + return (RegexPackage)getEPackage(); + } + + /** + * + * + * @deprecated + * @generated + */ + public static RegexPackage getPackage() { + return RegexPackage.eINSTANCE; + } + +} //RegexFactoryImpl diff --git a/com.ibm.wala.emf/src/com/ibm/wala/ecore/regex/impl/RegexPackageImpl.java b/com.ibm.wala.emf/src/com/ibm/wala/ecore/regex/impl/RegexPackageImpl.java new file mode 100644 index 000000000..4c0c8041c --- /dev/null +++ b/com.ibm.wala.emf/src/com/ibm/wala/ecore/regex/impl/RegexPackageImpl.java @@ -0,0 +1,242 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.regex.impl; + +import com.ibm.wala.ecore.common.CommonPackage; + +import com.ibm.wala.ecore.common.impl.CommonPackageImpl; + +import com.ibm.wala.ecore.graph.GraphPackage; + +import com.ibm.wala.ecore.graph.impl.GraphPackageImpl; + +import com.ibm.wala.ecore.j2ee.scope.J2EEScopePackage; + +import com.ibm.wala.ecore.j2ee.scope.impl.J2EEScopePackageImpl; + +import com.ibm.wala.ecore.java.JavaPackage; + +import com.ibm.wala.ecore.java.callGraph.CallGraphPackage; + +import com.ibm.wala.ecore.java.callGraph.impl.CallGraphPackageImpl; + +import com.ibm.wala.ecore.java.impl.JavaPackageImpl; + +import com.ibm.wala.ecore.java.pointerAnalysis.PointerAnalysisPackage; + +import com.ibm.wala.ecore.java.pointerAnalysis.impl.PointerAnalysisPackageImpl; + +import com.ibm.wala.ecore.java.scope.JavaScopePackage; + +import com.ibm.wala.ecore.java.scope.impl.JavaScopePackageImpl; + +import com.ibm.wala.ecore.perf.PerfPackage; + +import com.ibm.wala.ecore.perf.impl.PerfPackageImpl; + +import com.ibm.wala.ecore.regex.EPattern; +import com.ibm.wala.ecore.regex.RegexFactory; +import com.ibm.wala.ecore.regex.RegexPackage; + +import org.eclipse.emf.ecore.EAttribute; +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EPackage; + +import org.eclipse.emf.ecore.impl.EPackageImpl; + +/** + * + * An implementation of the model Package. + * + * @generated + */ +public class RegexPackageImpl extends EPackageImpl implements RegexPackage { + /** + * + * + * @generated + */ + private EClass ePatternEClass = null; + + /** + * Creates an instance of the model Package, registered with + * {@link org.eclipse.emf.ecore.EPackage.Registry EPackage.Registry} by the package + * package URI value. + *

                              Note: the correct way to create the package is via the static + * factory method {@link #init init()}, which also performs + * initialization of the package, or returns the registered package, + * if one already exists. + * + * + * @see org.eclipse.emf.ecore.EPackage.Registry + * @see com.ibm.wala.ecore.regex.RegexPackage#eNS_URI + * @see #init() + * @generated + */ + private RegexPackageImpl() { + super(eNS_URI, RegexFactory.eINSTANCE); + } + + /** + * + * + * @generated + */ + private static boolean isInited = false; + + /** + * Creates, registers, and initializes the Package for this + * model, and for any others upon which it depends. Simple + * dependencies are satisfied by calling this method on all + * dependent packages before doing anything else. This method drives + * initialization for interdependent packages directly, in parallel + * with this package, itself. + *

                              Of this package and its interdependencies, all packages which + * have not yet been registered by their URI values are first created + * and registered. The packages are then initialized in two steps: + * meta-model objects for all of the packages are created before any + * are initialized, since one package's meta-model objects may refer to + * those of another. + *

                              Invocation of this method will not affect any packages that have + * already been initialized. + * + * + * @see #eNS_URI + * @see #createPackageContents() + * @see #initializePackageContents() + * @generated + */ + public static RegexPackage init() { + if (isInited) return (RegexPackage)EPackage.Registry.INSTANCE.getEPackage(RegexPackage.eNS_URI); + + // Obtain or create and register package + RegexPackageImpl theRegexPackage = (RegexPackageImpl)(EPackage.Registry.INSTANCE.getEPackage(eNS_URI) instanceof RegexPackageImpl ? EPackage.Registry.INSTANCE.getEPackage(eNS_URI) : new RegexPackageImpl()); + + isInited = true; + + // Obtain or create and register interdependencies + GraphPackageImpl theGraphPackage = (GraphPackageImpl)(EPackage.Registry.INSTANCE.getEPackage(GraphPackage.eNS_URI) instanceof GraphPackageImpl ? EPackage.Registry.INSTANCE.getEPackage(GraphPackage.eNS_URI) : GraphPackage.eINSTANCE); + CommonPackageImpl theCommonPackage = (CommonPackageImpl)(EPackage.Registry.INSTANCE.getEPackage(CommonPackage.eNS_URI) instanceof CommonPackageImpl ? EPackage.Registry.INSTANCE.getEPackage(CommonPackage.eNS_URI) : CommonPackage.eINSTANCE); + PerfPackageImpl thePerfPackage = (PerfPackageImpl)(EPackage.Registry.INSTANCE.getEPackage(PerfPackage.eNS_URI) instanceof PerfPackageImpl ? EPackage.Registry.INSTANCE.getEPackage(PerfPackage.eNS_URI) : PerfPackage.eINSTANCE); + JavaPackageImpl theJavaPackage = (JavaPackageImpl)(EPackage.Registry.INSTANCE.getEPackage(JavaPackage.eNS_URI) instanceof JavaPackageImpl ? EPackage.Registry.INSTANCE.getEPackage(JavaPackage.eNS_URI) : JavaPackage.eINSTANCE); + CallGraphPackageImpl theCallGraphPackage = (CallGraphPackageImpl)(EPackage.Registry.INSTANCE.getEPackage(CallGraphPackage.eNS_URI) instanceof CallGraphPackageImpl ? EPackage.Registry.INSTANCE.getEPackage(CallGraphPackage.eNS_URI) : CallGraphPackage.eINSTANCE); + PointerAnalysisPackageImpl thePointerAnalysisPackage = (PointerAnalysisPackageImpl)(EPackage.Registry.INSTANCE.getEPackage(PointerAnalysisPackage.eNS_URI) instanceof PointerAnalysisPackageImpl ? EPackage.Registry.INSTANCE.getEPackage(PointerAnalysisPackage.eNS_URI) : PointerAnalysisPackage.eINSTANCE); + JavaScopePackageImpl theJavaScopePackage = (JavaScopePackageImpl)(EPackage.Registry.INSTANCE.getEPackage(JavaScopePackage.eNS_URI) instanceof JavaScopePackageImpl ? EPackage.Registry.INSTANCE.getEPackage(JavaScopePackage.eNS_URI) : JavaScopePackage.eINSTANCE); + J2EEScopePackageImpl theJ2EEScopePackage = (J2EEScopePackageImpl)(EPackage.Registry.INSTANCE.getEPackage(J2EEScopePackage.eNS_URI) instanceof J2EEScopePackageImpl ? EPackage.Registry.INSTANCE.getEPackage(J2EEScopePackage.eNS_URI) : J2EEScopePackage.eINSTANCE); + + // Create package meta-data objects + theRegexPackage.createPackageContents(); + theGraphPackage.createPackageContents(); + theCommonPackage.createPackageContents(); + thePerfPackage.createPackageContents(); + theJavaPackage.createPackageContents(); + theCallGraphPackage.createPackageContents(); + thePointerAnalysisPackage.createPackageContents(); + theJavaScopePackage.createPackageContents(); + theJ2EEScopePackage.createPackageContents(); + + // Initialize created meta-data + theRegexPackage.initializePackageContents(); + theGraphPackage.initializePackageContents(); + theCommonPackage.initializePackageContents(); + thePerfPackage.initializePackageContents(); + theJavaPackage.initializePackageContents(); + theCallGraphPackage.initializePackageContents(); + thePointerAnalysisPackage.initializePackageContents(); + theJavaScopePackage.initializePackageContents(); + theJ2EEScopePackage.initializePackageContents(); + + // Mark meta-data to indicate it can't be changed + theRegexPackage.freeze(); + + return theRegexPackage; + } + + /** + * + * + * @generated + */ + public EClass getEPattern() { + return ePatternEClass; + } + + /** + * + * + * @generated + */ + public EAttribute getEPattern_Pattern() { + return (EAttribute)ePatternEClass.getEStructuralFeatures().get(0); + } + + /** + * + * + * @generated + */ + public RegexFactory getRegexFactory() { + return (RegexFactory)getEFactoryInstance(); + } + + /** + * + * + * @generated + */ + private boolean isCreated = false; + + /** + * Creates the meta-model objects for the package. This method is + * guarded to have no affect on any invocation but its first. + * + * + * @generated + */ + public void createPackageContents() { + if (isCreated) return; + isCreated = true; + + // Create classes and their features + ePatternEClass = createEClass(EPATTERN); + createEAttribute(ePatternEClass, EPATTERN__PATTERN); + } + + /** + * + * + * @generated + */ + private boolean isInitialized = false; + + /** + * Complete the initialization of the package and its meta-model. This + * method is guarded to have no affect on any invocation but its first. + * + * + * @generated + */ + public void initializePackageContents() { + if (isInitialized) return; + isInitialized = true; + + // Initialize package + setName(eNAME); + setNsPrefix(eNS_PREFIX); + setNsURI(eNS_URI); + + // Add supertypes to classes + + // Initialize classes and features; add operations and parameters + initEClass(ePatternEClass, EPattern.class, "EPattern", !IS_ABSTRACT, !IS_INTERFACE, IS_GENERATED_INSTANCE_CLASS); + initEAttribute(getEPattern_Pattern(), ecorePackage.getEString(), "pattern", null, 1, 1, EPattern.class, !IS_TRANSIENT, !IS_VOLATILE, IS_CHANGEABLE, !IS_UNSETTABLE, !IS_ID, IS_UNIQUE, !IS_DERIVED, IS_ORDERED); + + // Create resource + createResource(eNS_URI); + } + +} //RegexPackageImpl diff --git a/com.ibm.wala.emf/src/com/ibm/wala/ecore/regex/util/RegexAdapterFactory.java b/com.ibm.wala.emf/src/com/ibm/wala/ecore/regex/util/RegexAdapterFactory.java new file mode 100644 index 000000000..9613970b9 --- /dev/null +++ b/com.ibm.wala.emf/src/com/ibm/wala/ecore/regex/util/RegexAdapterFactory.java @@ -0,0 +1,120 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.regex.util; + +import com.ibm.wala.ecore.regex.*; + +import org.eclipse.emf.common.notify.Adapter; +import org.eclipse.emf.common.notify.Notifier; + +import org.eclipse.emf.common.notify.impl.AdapterFactoryImpl; + +import org.eclipse.emf.ecore.EObject; + +/** + * + * The Adapter Factory for the model. + * It provides an adapter createXXX method for each class of the model. + * + * @see com.ibm.wala.ecore.regex.RegexPackage + * @generated + */ +public class RegexAdapterFactory extends AdapterFactoryImpl { + /** + * The cached model package. + * + * + * @generated + */ + protected static RegexPackage modelPackage; + + /** + * Creates an instance of the adapter factory. + * + * + * @generated + */ + public RegexAdapterFactory() { + if (modelPackage == null) { + modelPackage = RegexPackage.eINSTANCE; + } + } + + /** + * Returns whether this factory is applicable for the type of the object. + * + * This implementation returns true if the object is either the model's package or is an instance object of the model. + * + * @return whether this factory is applicable for the type of the object. + * @generated + */ + public boolean isFactoryForType(Object object) { + if (object == modelPackage) { + return true; + } + if (object instanceof EObject) { + return ((EObject)object).eClass().getEPackage() == modelPackage; + } + return false; + } + + /** + * The switch the delegates to the createXXX methods. + * + * + * @generated + */ + protected RegexSwitch modelSwitch = + new RegexSwitch() { + public Object caseEPattern(EPattern object) { + return createEPatternAdapter(); + } + public Object defaultCase(EObject object) { + return createEObjectAdapter(); + } + }; + + /** + * Creates an adapter for the target. + * + * + * @param target the object to adapt. + * @return the adapter for the target. + * @generated + */ + public Adapter createAdapter(Notifier target) { + return (Adapter)modelSwitch.doSwitch((EObject)target); + } + + + /** + * Creates a new adapter for an object of class '{@link com.ibm.wala.ecore.regex.EPattern EPattern}'. + * + * This default implementation returns null so that we can easily ignore cases; + * it's useful to ignore a case when inheritance will catch all the cases anyway. + * + * @return the new adapter. + * @see com.ibm.wala.ecore.regex.EPattern + * @generated + */ + public Adapter createEPatternAdapter() { + return null; + } + + /** + * Creates a new adapter for the default case. + * + * This default implementation returns null. + * + * @return the new adapter. + * @generated + */ + public Adapter createEObjectAdapter() { + return null; + } + +} //RegexAdapterFactory diff --git a/com.ibm.wala.emf/src/com/ibm/wala/ecore/regex/util/RegexSwitch.java b/com.ibm.wala.emf/src/com/ibm/wala/ecore/regex/util/RegexSwitch.java new file mode 100644 index 000000000..8b4c0184f --- /dev/null +++ b/com.ibm.wala.emf/src/com/ibm/wala/ecore/regex/util/RegexSwitch.java @@ -0,0 +1,130 @@ +/** + * + * + * + * $Id$ + */ +package com.ibm.wala.ecore.regex.util; + +import com.ibm.wala.ecore.regex.*; + +import java.util.List; + +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EObject; + +/** + * + * The Switch for the model's inheritance hierarchy. + * It supports the call {@link #doSwitch(EObject) doSwitch(object)} + * to invoke the caseXXX method for each class of the model, + * starting with the actual class of the object + * and proceeding up the inheritance hierarchy + * until a non-null result is returned, + * which is the result of the switch. + * + * @see com.ibm.wala.ecore.regex.RegexPackage + * @generated + */ +public class RegexSwitch { + /** + * The cached model package + * + * + * @generated + */ + protected static RegexPackage modelPackage; + + /** + * Creates an instance of the switch. + * + * + * @generated + */ + public RegexSwitch() { + if (modelPackage == null) { + modelPackage = RegexPackage.eINSTANCE; + } + } + + /** + * Calls caseXXX for each class of the model until one returns a non null result; it yields that result. + * + * + * @return the first non-null result returned by a caseXXX call. + * @generated + */ + public Object doSwitch(EObject theEObject) { + return doSwitch(theEObject.eClass(), theEObject); + } + + /** + * Calls caseXXX for each class of the model until one returns a non null result; it yields that result. + * + * + * @return the first non-null result returned by a caseXXX call. + * @generated + */ + protected Object doSwitch(EClass theEClass, EObject theEObject) { + if (theEClass.eContainer() == modelPackage) { + return doSwitch(theEClass.getClassifierID(), theEObject); + } + else { + List eSuperTypes = theEClass.getESuperTypes(); + return + eSuperTypes.isEmpty() ? + defaultCase(theEObject) : + doSwitch((EClass)eSuperTypes.get(0), theEObject); + } + } + + /** + * Calls caseXXX for each class of the model until one returns a non null result; it yields that result. + * + * + * @return the first non-null result returned by a caseXXX call. + * @generated + */ + protected Object doSwitch(int classifierID, EObject theEObject) { + switch (classifierID) { + case RegexPackage.EPATTERN: { + EPattern ePattern = (EPattern)theEObject; + Object result = caseEPattern(ePattern); + if (result == null) result = defaultCase(theEObject); + return result; + } + default: return defaultCase(theEObject); + } + } + + /** + * Returns the result of interpretting the object as an instance of 'EPattern'. + * + * This implementation returns null; + * returning a non-null result will terminate the switch. + * + * @param object the target of the switch. + * @return the result of interpretting the object as an instance of 'EPattern'. + * @see #doSwitch(org.eclipse.emf.ecore.EObject) doSwitch(EObject) + * @generated + */ + public Object caseEPattern(EPattern object) { + return null; + } + + /** + * Returns the result of interpretting the object as an instance of 'EObject'. + * + * This implementation returns null; + * returning a non-null result will terminate the switch, but this is the last case anyway. + * + * @param object the target of the switch. + * @return the result of interpretting the object as an instance of 'EObject'. + * @see #doSwitch(org.eclipse.emf.ecore.EObject) + * @generated + */ + public Object defaultCase(EObject object) { + return null; + } + +} //RegexSwitch diff --git a/com.ibm.wala.j2ee/.classpath b/com.ibm.wala.j2ee/.classpath new file mode 100644 index 000000000..dcc145b0d --- /dev/null +++ b/com.ibm.wala.j2ee/.classpath @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/com.ibm.wala.j2ee/.project b/com.ibm.wala.j2ee/.project new file mode 100644 index 000000000..c82df7921 --- /dev/null +++ b/com.ibm.wala.j2ee/.project @@ -0,0 +1,39 @@ + + + com.ibm.wala.j2ee + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + com.ibm.etools.ctc.serviceprojectbuilder + + + + + com.ibm.etools.validation.validationbuilder + + + + + + org.eclipse.jdt.core.javanature + org.eclipse.pde.PluginNature + com.ibm.etools.ctc.javaprojectnature + + diff --git a/com.ibm.wala.j2ee/.settings/org.eclipse.jdt.core.prefs b/com.ibm.wala.j2ee/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 000000000..bea2e4df6 --- /dev/null +++ b/com.ibm.wala.j2ee/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,62 @@ +#Fri Nov 10 08:55:53 EST 2006 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5 +org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve +org.eclipse.jdt.core.compiler.compliance=1.5 +org.eclipse.jdt.core.compiler.debug.lineNumber=generate +org.eclipse.jdt.core.compiler.debug.localVariable=generate +org.eclipse.jdt.core.compiler.debug.sourceFile=generate +org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.autoboxing=ignore +org.eclipse.jdt.core.compiler.problem.deprecation=ignore +org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled +org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled +org.eclipse.jdt.core.compiler.problem.discouragedReference=ignore +org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore +org.eclipse.jdt.core.compiler.problem.fieldHiding=ignore +org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning +org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning +org.eclipse.jdt.core.compiler.problem.forbiddenReference=error +org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning +org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning +org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=ignore +org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore +org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore +org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning +org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore +org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore +org.eclipse.jdt.core.compiler.problem.missingSerialVersion=ignore +org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning +org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning +org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore +org.eclipse.jdt.core.compiler.problem.nullReference=ignore +org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning +org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore +org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=ignore +org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning +org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled +org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning +org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled +org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore +org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning +org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning +org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore +org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning +org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore +org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=ignore +org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled +org.eclipse.jdt.core.compiler.problem.unusedImport=warning +org.eclipse.jdt.core.compiler.problem.unusedLabel=warning +org.eclipse.jdt.core.compiler.problem.unusedLocal=warning +org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore +org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled +org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled +org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning +org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning +org.eclipse.jdt.core.compiler.source=1.5 diff --git a/com.ibm.wala.j2ee/.settings/org.eclipse.jdt.ui.prefs b/com.ibm.wala.j2ee/.settings/org.eclipse.jdt.ui.prefs new file mode 100644 index 000000000..b0888c8af --- /dev/null +++ b/com.ibm.wala.j2ee/.settings/org.eclipse.jdt.ui.prefs @@ -0,0 +1,3 @@ +#Wed Oct 04 21:45:25 EDT 2006 +eclipse.preferences.version=1 +internal.default.compliance=default diff --git a/com.ibm.wala.j2ee/META-INF/MANIFEST.MF b/com.ibm.wala.j2ee/META-INF/MANIFEST.MF new file mode 100644 index 000000000..f2fbcaf68 --- /dev/null +++ b/com.ibm.wala.j2ee/META-INF/MANIFEST.MF @@ -0,0 +1,22 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: %PLUGINNAME +Bundle-SymbolicName: com.ibm.wala.j2ee +Bundle-Version: 1.0.0 +Bundle-Vendor: %VENDORNAME +Bundle-Localization: plugin +Export-Package: ., + com.ibm.wala.j2ee, + com.ibm.wala.j2ee.client, + com.ibm.wala.j2ee.client.impl, + com.ibm.wala.j2ee.util +Require-Bundle: com.ibm.wala.core;visibility:=reexport, + org.eclipse.jem;visibility:=reexport, + org.eclipse.jst.j2ee.core;visibility:=reexport, + org.eclipse.wst.common.emf, + org.eclipse.jem.util, + org.eclipse.jem.workbench, + org.eclipse.wst.common.frameworks, + org.eclipse.emf.ecore.xmi, + com.ibm.icu;visibility:=reexport, + org.eclipse.equinox.servlet.api;visibility:=reexport diff --git a/com.ibm.wala.j2ee/build.properties b/com.ibm.wala.j2ee/build.properties new file mode 100644 index 000000000..95b7c9ea9 --- /dev/null +++ b/com.ibm.wala.j2ee/build.properties @@ -0,0 +1,11 @@ +bin.includes = dat/DefaultWebsphereModules.xml,\ + dat/J2EEClassHierarchyExclusions.xml,\ + dat/SyntheticContainerModel.xml,\ + dat/benignext.xml,\ + META-INF/,\ + . +jars.compile.order = . +output.. = bin/ +source.. = dat/,\ + src/,\ + lib/ diff --git a/com.ibm.wala.j2ee/build.xml b/com.ibm.wala.j2ee/build.xml new file mode 100644 index 000000000..4eacabd13 --- /dev/null +++ b/com.ibm.wala.j2ee/build.xml @@ -0,0 +1,238 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/com.ibm.wala.j2ee/dat/DefaultWebsphereModules.xml b/com.ibm.wala.j2ee/dat/DefaultWebsphereModules.xml new file mode 100644 index 000000000..c03441594 --- /dev/null +++ b/com.ibm.wala.j2ee/dat/DefaultWebsphereModules.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/com.ibm.wala.j2ee/dat/J2EEClassHierarchyExclusions.xml b/com.ibm.wala.j2ee/dat/J2EEClassHierarchyExclusions.xml new file mode 100644 index 000000000..fcc591805 --- /dev/null +++ b/com.ibm.wala.j2ee/dat/J2EEClassHierarchyExclusions.xml @@ -0,0 +1,384 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/com.ibm.wala.j2ee/dat/SyntheticContainerModel.xml b/com.ibm.wala.j2ee/dat/SyntheticContainerModel.xml new file mode 100644 index 000000000..c4598993c --- /dev/null +++ b/com.ibm.wala.j2ee/dat/SyntheticContainerModel.xml @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/com.ibm.wala.j2ee/dat/benignext.xml b/com.ibm.wala.j2ee/dat/benignext.xml new file mode 100644 index 000000000..6b852e95a --- /dev/null +++ b/com.ibm.wala.j2ee/dat/benignext.xml @@ -0,0 +1,560 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/com.ibm.wala.j2ee/javaCompiler...args b/com.ibm.wala.j2ee/javaCompiler...args new file mode 100644 index 000000000..75a9aeff3 --- /dev/null +++ b/com.ibm.wala.j2ee/javaCompiler...args @@ -0,0 +1,76 @@ +#ADAPTER#ACCESS#com.ibm.wala.core/bin/[+com/ibm/wala/analysis/pointers/*;+com/ibm/wala/analysis/reflection/*;+com/ibm/wala/analysis/stackMachine/*;+com/ibm/wala/analysis/typeInference/*;+com/ibm/wala/cfg/*;+com/ibm/wala/cfg/cdg/*;+com/ibm/wala/classLoader/*;+com/ibm/wala/client/*;+com/ibm/wala/client/impl/*;+com/ibm/wala/core/plugin/*;+com/ibm/wala/dataflow/IFDS/*;+com/ibm/wala/dataflow/graph/*;+com/ibm/wala/dataflow/ssa/*;+com/ibm/wala/emf/wrappers/*;+com/ibm/wala/escape/*;+com/ibm/wala/fixedpoint/impl/*;+com/ibm/wala/fixpoint/*;+com/ibm/wala/ipa/callgraph/*;+com/ibm/wala/ipa/callgraph/impl/*;+com/ibm/wala/ipa/callgraph/propagation/*;+com/ibm/wala/ipa/callgraph/propagation/cfa/*;+com/ibm/wala/ipa/callgraph/propagation/rta/*;+com/ibm/wala/ipa/cfg/*;+com/ibm/wala/ipa/cha/*;+com/ibm/wala/ipa/summaries/*;+com/ibm/wala/model/*;+com/ibm/wala/model/java/lang/*;+com/ibm/wala/properties/*;+com/ibm/wala/ssa/*;+com/ibm/wala/ssa/analysis/*;+com/ibm/wala/types/*;+com/ibm/wala/util/*;+com/ibm/wala/util/bytecode/*;+com/ibm/wala/util/collections/*;+com/ibm/wala/util/config/*;+com/ibm/wala/util/debug/*;+com/ibm/wala/util/graph/*;+com/ibm/wala/util/graph/impl/*;+com/ibm/wala/util/graph/traverse/*;+com/ibm/wala/util/heapTrace/*;+com/ibm/wala/util/intertionalization/*;+com/ibm/wala/util/intset/*;+com/ibm/wala/util/io/*;+com/ibm/wala/util/logging/*;+com/ibm/wala/util/math/*;+com/ibm/wala/util/perf/*;+com/ibm/wala/util/properties/*;+com/ibm/wala/util/properties/impl/*;+com/ibm/wala/util/warnings/*;+com/ibm/wala/viz/*;?**/*] +#ADAPTER#ACCESS#com.ibm.wala.core/@dot[+com/ibm/wala/analysis/pointers/*;+com/ibm/wala/analysis/reflection/*;+com/ibm/wala/analysis/stackMachine/*;+com/ibm/wala/analysis/typeInference/*;+com/ibm/wala/cfg/*;+com/ibm/wala/cfg/cdg/*;+com/ibm/wala/classLoader/*;+com/ibm/wala/client/*;+com/ibm/wala/client/impl/*;+com/ibm/wala/core/plugin/*;+com/ibm/wala/dataflow/IFDS/*;+com/ibm/wala/dataflow/graph/*;+com/ibm/wala/dataflow/ssa/*;+com/ibm/wala/emf/wrappers/*;+com/ibm/wala/escape/*;+com/ibm/wala/fixedpoint/impl/*;+com/ibm/wala/fixpoint/*;+com/ibm/wala/ipa/callgraph/*;+com/ibm/wala/ipa/callgraph/impl/*;+com/ibm/wala/ipa/callgraph/propagation/*;+com/ibm/wala/ipa/callgraph/propagation/cfa/*;+com/ibm/wala/ipa/callgraph/propagation/rta/*;+com/ibm/wala/ipa/cfg/*;+com/ibm/wala/ipa/cha/*;+com/ibm/wala/ipa/summaries/*;+com/ibm/wala/model/*;+com/ibm/wala/model/java/lang/*;+com/ibm/wala/properties/*;+com/ibm/wala/ssa/*;+com/ibm/wala/ssa/analysis/*;+com/ibm/wala/types/*;+com/ibm/wala/util/*;+com/ibm/wala/util/bytecode/*;+com/ibm/wala/util/collections/*;+com/ibm/wala/util/config/*;+com/ibm/wala/util/debug/*;+com/ibm/wala/util/graph/*;+com/ibm/wala/util/graph/impl/*;+com/ibm/wala/util/graph/traverse/*;+com/ibm/wala/util/heapTrace/*;+com/ibm/wala/util/intertionalization/*;+com/ibm/wala/util/intset/*;+com/ibm/wala/util/io/*;+com/ibm/wala/util/logging/*;+com/ibm/wala/util/math/*;+com/ibm/wala/util/perf/*;+com/ibm/wala/util/properties/*;+com/ibm/wala/util/properties/impl/*;+com/ibm/wala/util/warnings/*;+com/ibm/wala/viz/*;?**/*] +#ADAPTER#ACCESS#com.ibm.wala.emf/bin/[+com/ibm/wala/ecore/common/*;+com/ibm/wala/ecore/common/impl/*;+com/ibm/wala/ecore/common/util/*;+com/ibm/wala/ecore/graph/*;+com/ibm/wala/ecore/graph/impl/*;+com/ibm/wala/ecore/graph/util/*;+com/ibm/wala/ecore/j2ee/scope/*;+com/ibm/wala/ecore/j2ee/scope/impl/*;+com/ibm/wala/ecore/j2ee/scope/util/*;+com/ibm/wala/ecore/java/*;+com/ibm/wala/ecore/java/callGraph/*;+com/ibm/wala/ecore/java/callGraph/impl/*;+com/ibm/wala/ecore/java/callGraph/util/*;+com/ibm/wala/ecore/java/impl/*;+com/ibm/wala/ecore/java/pointerAnalysis/*;+com/ibm/wala/ecore/java/pointerAnalysis/impl/*;+com/ibm/wala/ecore/java/pointerAnalysis/util/*;+com/ibm/wala/ecore/java/scope/*;+com/ibm/wala/ecore/java/scope/impl/*;+com/ibm/wala/ecore/java/scope/util/*;+com/ibm/wala/ecore/java/util/*;+com/ibm/wala/ecore/perf/*;+com/ibm/wala/ecore/perf/impl/*;+com/ibm/wala/ecore/perf/util/*;+com/ibm/wala/ecore/regex/*;+com/ibm/wala/ecore/regex/impl/*;+com/ibm/wala/ecore/regex/util/*;?**/*] +#ADAPTER#ACCESS#com.ibm.wala.emf/@dot[+com/ibm/wala/ecore/common/*;+com/ibm/wala/ecore/common/impl/*;+com/ibm/wala/ecore/common/util/*;+com/ibm/wala/ecore/graph/*;+com/ibm/wala/ecore/graph/impl/*;+com/ibm/wala/ecore/graph/util/*;+com/ibm/wala/ecore/j2ee/scope/*;+com/ibm/wala/ecore/j2ee/scope/impl/*;+com/ibm/wala/ecore/j2ee/scope/util/*;+com/ibm/wala/ecore/java/*;+com/ibm/wala/ecore/java/callGraph/*;+com/ibm/wala/ecore/java/callGraph/impl/*;+com/ibm/wala/ecore/java/callGraph/util/*;+com/ibm/wala/ecore/java/impl/*;+com/ibm/wala/ecore/java/pointerAnalysis/*;+com/ibm/wala/ecore/java/pointerAnalysis/impl/*;+com/ibm/wala/ecore/java/pointerAnalysis/util/*;+com/ibm/wala/ecore/java/scope/*;+com/ibm/wala/ecore/java/scope/impl/*;+com/ibm/wala/ecore/java/scope/util/*;+com/ibm/wala/ecore/java/util/*;+com/ibm/wala/ecore/perf/*;+com/ibm/wala/ecore/perf/impl/*;+com/ibm/wala/ecore/perf/util/*;+com/ibm/wala/ecore/regex/*;+com/ibm/wala/ecore/regex/impl/*;+com/ibm/wala/ecore/regex/util/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.core.runtime_3.2.0.v20060603.jar[~org/eclipse/core/internal/preferences/legacy/*;~org/eclipse/core/internal/runtime/*;+org/eclipse/core/runtime/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.osgi_3.2.0.v20060601.jar[+org/eclipse/osgi/event/*;+org/eclipse/osgi/framework/console/*;+org/eclipse/osgi/framework/eventmgr/*;+org/eclipse/osgi/framework/log/*;+org/eclipse/osgi/service/datalocation/*;+org/eclipse/osgi/service/debug/*;+org/eclipse/osgi/service/environment/*;+org/eclipse/osgi/service/localization/*;+org/eclipse/osgi/service/pluginconversion/*;+org/eclipse/osgi/service/resolver/*;+org/eclipse/osgi/service/runnable/*;+org/eclipse/osgi/service/urlconversion/*;+org/eclipse/osgi/storagemanager/*;+org/eclipse/osgi/util/*;+org/osgi/framework/*;+org/osgi/service/condpermadmin/*;+org/osgi/service/packageadmin/*;+org/osgi/service/permissionadmin/*;+org/osgi/service/startlevel/*;+org/osgi/service/url/*;+org/osgi/util/tracker/*;~org/eclipse/core/runtime/adaptor/*;~org/eclipse/core/runtime/internal/adaptor/*;~org/eclipse/core/runtime/internal/stats/*;~org/eclipse/osgi/baseadaptor/*;~org/eclipse/osgi/baseadaptor/bundlefile/*;~org/eclipse/osgi/baseadaptor/hooks/*;~org/eclipse/osgi/baseadaptor/loader/*;~org/eclipse/osgi/framework/adaptor/*;~org/eclipse/osgi/framework/debug/*;~org/eclipse/osgi/framework/internal/core/*;~org/eclipse/osgi/framework/internal/protocol/*;~org/eclipse/osgi/framework/internal/protocol/bundleentry/*;~org/eclipse/osgi/framework/internal/protocol/bundleresource/*;~org/eclipse/osgi/framework/internal/protocol/reference/*;~org/eclipse/osgi/framework/internal/reliablefile/*;~org/eclipse/osgi/framework/launcher/*;~org/eclipse/osgi/framework/util/*;~org/eclipse/osgi/internal/baseadaptor/*;~org/eclipse/osgi/internal/module/*;~org/eclipse/osgi/internal/profile/*;~org/eclipse/osgi/internal/resolver/*;~org/eclipse/osgi/internal/verifier/*;~org/eclipse/osgi/internal/provisional/verifier/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.equinox.common_3.2.0.v20060603.jar[~org/eclipse/core/internal/runtime/*;~org/eclipse/core/internal/boot/*;+org/eclipse/core/runtime/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.core.jobs_3.2.0.v20060603.jar[~org/eclipse/core/internal/jobs/*;+org/eclipse/core/runtime/jobs/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.core.runtime.compatibility.registry_3.2.0.v20060603/runtime_registry_compatibility.jar[~org/eclipse/core/internal/registry/*;~org/eclipse/core/internal/registry/osgi/*;~org/eclipse/core/internal/registry/spi/*;+org/eclipse/core/runtime/*;+org/eclipse/core/runtime/dynamichelpers/*;+org/eclipse/core/runtime/spi/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.core.runtime.compatibility.registry_3.2.0.v20060603[~org/eclipse/core/internal/registry/*;~org/eclipse/core/internal/registry/osgi/*;~org/eclipse/core/internal/registry/spi/*;+org/eclipse/core/runtime/*;+org/eclipse/core/runtime/dynamichelpers/*;+org/eclipse/core/runtime/spi/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.equinox.registry_3.2.0.v20060601.jar[~org/eclipse/core/internal/registry/*;~org/eclipse/core/internal/registry/osgi/*;~org/eclipse/core/internal/registry/spi/*;+org/eclipse/core/runtime/*;+org/eclipse/core/runtime/dynamichelpers/*;+org/eclipse/core/runtime/spi/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.apache.xerces_2.8.0.v200606131651/resolver.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.apache.xerces_2.8.0.v200606131651/xercesImpl.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.apache.xerces_2.8.0.v200606131651/xml-apis.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.equinox.preferences_3.2.0.v20060601.jar[~org/eclipse/core/internal/preferences/*;~org/eclipse/core/internal/preferences/exchange/*;+org/eclipse/core/runtime/preferences/*;+org/osgi/service/prefs/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.core.runtime.compatibility.registry_3.2.0.v20060603/@dot[~org/eclipse/core/internal/registry/*;~org/eclipse/core/internal/registry/osgi/*;~org/eclipse/core/internal/registry/spi/*;+org/eclipse/core/runtime/*;+org/eclipse/core/runtime/dynamichelpers/*;+org/eclipse/core/runtime/spi/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.core.contenttype_3.2.0.v20060603.jar[~org/eclipse/core/internal/content/*;+org/eclipse/core/runtime/content/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.core.runtime.compatibility.auth_3.2.0.v20060601.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.emf.ecore_2.2.0.v200606271057.jar[+org/eclipse/emf/ecore/*;+org/eclipse/emf/ecore/impl/*;+org/eclipse/emf/ecore/plugin/*;+org/eclipse/emf/ecore/resource/*;+org/eclipse/emf/ecore/resource/impl/*;+org/eclipse/emf/ecore/util/*;+org/eclipse/emf/ecore/xml/namespace/*;+org/eclipse/emf/ecore/xml/namespace/impl/*;+org/eclipse/emf/ecore/xml/namespace/util/*;+org/eclipse/emf/ecore/xml/type/*;+org/eclipse/emf/ecore/xml/type/impl/*;+org/eclipse/emf/ecore/xml/type/internal/*;+org/eclipse/emf/ecore/xml/type/util/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.emf.common_2.2.0.v200606271057.jar[+org/eclipse/emf/common/*;+org/eclipse/emf/common/archive/*;+org/eclipse/emf/common/command/*;+org/eclipse/emf/common/notify/*;+org/eclipse/emf/common/notify/impl/*;+org/eclipse/emf/common/util/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.core.resources_3.2.0.v20060603.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.core.resources.compatibility_3.2.0.v20060603.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.core.resources.win32_3.2.0.v20060603.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.core.runtime.compatibility_3.1.100.v20060603.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.update.configurator_3.2.0.v20060605.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.ant.core_3.1.100.v20060531.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.core.variables_3.1.100.v20060605.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.core.expressions_3.2.0.v20060605-1400.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.core.filesystem_1.0.0.v20060603.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.core.filesystem.win32.x86_1.0.0.v20060603.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.emf.ecore.xmi_2.2.0.v200606271057.jar[+org/eclipse/emf/ecore/xmi/*;+org/eclipse/emf/ecore/xmi/impl/*;+org/eclipse/emf/ecore/xmi/util/*;?**/*] +#ADAPTER#ACCESS#com.ibm.wala.shrike/bin/[+com/ibm/wala/shrike/bench/*;+com/ibm/wala/shrike/copywriter/*;+com/ibm/wala/shrike/tools/*;+com/ibm/wala/shrikeBT/*;+com/ibm/wala/shrikeBT/analysis/*;+com/ibm/wala/shrikeBT/info/*;+com/ibm/wala/shrikeBT/shrikeCT/*;+com/ibm/wala/shrikeBT/shrikeCT/tools/*;+com/ibm/wala/shrikeBT/tools/*;+com/ibm/wala/shrikeCT/*;?**/*] +#ADAPTER#ACCESS#com.ibm.wala.shrike/@dot[+com/ibm/wala/shrike/bench/*;+com/ibm/wala/shrike/copywriter/*;+com/ibm/wala/shrike/tools/*;+com/ibm/wala/shrikeBT/*;+com/ibm/wala/shrikeBT/analysis/*;+com/ibm/wala/shrikeBT/info/*;+com/ibm/wala/shrikeBT/shrikeCT/*;+com/ibm/wala/shrikeBT/shrikeCT/tools/*;+com/ibm/wala/shrikeBT/tools/*;+com/ibm/wala/shrikeCT/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.jface_3.2.0.I20060605-1400.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.swt_3.2.0.v3232o.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.swt.win32.win32.x86_3.2.0.v3232m.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.core.commands_3.2.0.I20060605-1400.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.jdt.core_3.2.0.v_671.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.text_3.2.0.v20060605-1400.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/com.ibm.icu_3.4.4.1.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.team.core_3.2.0.I200606051140.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.jem_1.2.0.v20060530_RC2.jar[~org/eclipse/jem/internal/core/*;+org/eclipse/jem/internal/instantiation/*;+org/eclipse/jem/internal/instantiation/base/*;+org/eclipse/jem/internal/instantiation/impl/*;~org/eclipse/jem/internal/java/adapters/*;~org/eclipse/jem/internal/java/adapters/jdk/*;~org/eclipse/jem/internal/java/adapters/nls/*;+org/eclipse/jem/internal/java/beaninfo/*;~org/eclipse/jem/internal/java/init/*;+org/eclipse/jem/internal/java/instantiation/*;+org/eclipse/jem/java/*;+org/eclipse/jem/java/adapters/*;+org/eclipse/jem/java/impl/*;~org/eclipse/jem/java/internal/impl/*;+org/eclipse/jem/java/util/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.jem.proxy_1.2.0.v20060530_RC2.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.jdt.launching_3.2.0.v20060605.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.debug.core_3.2.0.v20060605.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.jdt.debug_3.2.0.v20060605/jdi.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.jdt.debug_3.2.0.v20060605/jdimodel.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.jdt.debug_3.2.0.v20060605/tools.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.jem.util_1.2.0.v20060530_RC2.jar[~org/eclipse/jem/internal/util/emf/workbench/*;~org/eclipse/jem/internal/util/emf/workbench/nature/*;~org/eclipse/jem/internal/util/emf/workbench/nls/*;+org/eclipse/jem/util/*;+org/eclipse/jem/util/emf/workbench/*;+org/eclipse/jem/util/emf/workbench/nature/*;+org/eclipse/jem/util/logger/*;+org/eclipse/jem/util/logger/proxy/*;+org/eclipse/jem/util/logger/proxyrender/*;+org/eclipse/jem/util/plugin/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.pde.core_3.2.0.v20060605.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.core.filebuffers_3.2.0.v20060605-1400.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.pde.build_3.2.0.v20060603/pdebuild.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.update.core_3.2.0.v20060605.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.update.core.win32_3.2.0.v20060605.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.ui_3.2.0.I20060605-1400.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.ui.workbench_3.2.0.I20060605-1400.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.ui.workbench.compatibility_3.2.0.I20060605-1400/@dot[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.ui.workbench.compatibility_3.2.0.I20060605-1400/compatibility.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.help_3.2.0.v20060602.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.jst.j2ee.core_1.1.0.v200606130315.jar[+org/eclipse/jst/j2ee/application/*;~org/eclipse/jst/j2ee/application/internal/impl/*;~org/eclipse/jst/j2ee/application/internal/util/*;+org/eclipse/jst/j2ee/client/*;~org/eclipse/jst/j2ee/client/internal/impl/*;~org/eclipse/jst/j2ee/client/internal/util/*;+org/eclipse/jst/j2ee/common/*;~org/eclipse/jst/j2ee/common/internal/impl/*;~org/eclipse/jst/j2ee/common/internal/util/*;~org/eclipse/jst/j2ee/commonarchivecore/internal/*;~org/eclipse/jst/j2ee/commonarchivecore/internal/exception/*;~org/eclipse/jst/j2ee/commonarchivecore/internal/helpers/*;~org/eclipse/jst/j2ee/commonarchivecore/internal/impl/*;~org/eclipse/jst/j2ee/commonarchivecore/internal/strategy/*;~org/eclipse/jst/j2ee/commonarchivecore/internal/util/*;~org/eclipse/jst/j2ee/commonarchivecore/looseconfig/internal/*;~org/eclipse/jst/j2ee/commonarchivecore/looseconfig/internal/impl/*;~org/eclipse/jst/j2ee/commonarchivecore/looseconfig/internal/util/*;+org/eclipse/jst/j2ee/core/internal/bindings/*;~org/eclipse/jst/j2ee/core/internal/plugin/*;+org/eclipse/jst/j2ee/ejb/*;~org/eclipse/jst/j2ee/ejb/internal/impl/*;~org/eclipse/jst/j2ee/ejb/internal/util/*;~org/eclipse/jst/j2ee/internal/*;~org/eclipse/jst/j2ee/internal/common/*;~org/eclipse/jst/j2ee/internal/model/translator/application/*;~org/eclipse/jst/j2ee/internal/model/translator/client/*;~org/eclipse/jst/j2ee/internal/model/translator/common/*;~org/eclipse/jst/j2ee/internal/model/translator/connector/*;~org/eclipse/jst/j2ee/internal/model/translator/ejb/*;~org/eclipse/jst/j2ee/internal/model/translator/webapplication/*;~org/eclipse/jst/j2ee/internal/model/translator/webservices/*;~org/eclipse/jst/j2ee/internal/xml/*;+org/eclipse/jst/j2ee/jca/*;~org/eclipse/jst/j2ee/jca/internal/impl/*;~org/eclipse/jst/j2ee/jca/internal/util/*;+org/eclipse/jst/j2ee/jsp/*;~org/eclipse/jst/j2ee/jsp/internal/impl/*;~org/eclipse/jst/j2ee/jsp/internal/util/*;~org/eclipse/jst/j2ee/model/internal/validation/*;~org/eclipse/jst/j2ee/taglib/internal/*;~org/eclipse/jst/j2ee/taglib/internal/impl/*;~org/eclipse/jst/j2ee/taglib/internal/util/*;+org/eclipse/jst/j2ee/webapplication/*;~org/eclipse/jst/j2ee/webapplication/internal/impl/*;~org/eclipse/jst/j2ee/webapplication/internal/util/*;~org/eclipse/jst/j2ee/webservice/internal/*;~org/eclipse/jst/j2ee/webservice/internal/util/*;~org/eclipse/jst/j2ee/webservice/internal/wsdd/*;+org/eclipse/jst/j2ee/webservice/jaxrpcmap/*;~org/eclipse/jst/j2ee/webservice/jaxrpcmap/internal/impl/*;~org/eclipse/jst/j2ee/webservice/jaxrpcmap/internal/util/*;+org/eclipse/jst/j2ee/webservice/wsclient/*;~org/eclipse/jst/j2ee/webservice/wsclient/internal/impl/*;~org/eclipse/jst/j2ee/webservice/wsclient/internal/util/*;+org/eclipse/jst/j2ee/webservice/wscommon/*;~org/eclipse/jst/j2ee/webservice/wscommon/internal/impl/*;~org/eclipse/jst/j2ee/webservice/wscommon/internal/util/*;+org/eclipse/jst/j2ee/webservice/wsdd/*;~org/eclipse/jst/j2ee/webservice/wsdd/internal/impl/*;~org/eclipse/jst/j2ee/webservice/wsdd/internal/util/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.wst.common.frameworks_1.1.0.v200606130645.jar[+org/eclipse/wst/common/frameworks/datamodel/*;+org/eclipse/wst/common/frameworks/datamodel/properties/*;~org/eclipse/wst/common/frameworks/internal/*;~org/eclipse/wst/common/frameworks/internal/activities/*;~org/eclipse/wst/common/frameworks/internal/datamodel/*;~org/eclipse/wst/common/frameworks/internal/enablement/*;~org/eclipse/wst/common/frameworks/internal/enablement/nonui/*;~org/eclipse/wst/common/frameworks/internal/operations/*;~org/eclipse/wst/common/frameworks/internal/plugin/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.wst.common.environment_1.0.100.v200606130645.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.osgi.util_3.1.100.v20060601.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.wst.common.emf_1.1.0.v200606130645.jar[~org/eclipse/wst/common/internal/emf/plugin/*;~org/eclipse/wst/common/internal/emf/resource/*;~org/eclipse/wst/common/internal/emf/utilities/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.wst.validation_1.1.0.v200606130645.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.wst.common.project.facet.core_1.1.0.v200606130645.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.wst.xml.core_1.1.0.v200606142000.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.wst.common.uriresolver_1.1.0.v200606130645.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.wst.sse.core_1.1.0.v200606141450.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.emf.ecore.edit_2.2.0.v200606271057.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.emf.edit_2.2.0.v200606271057.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.emf.ecore.change_2.2.0.v200606271057.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.wst.common.emfworkbench.integration_1.1.0.v200606130645.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.xsd_2.2.0.v200606271057.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.wst.common.core_1.1.0.v200606130645.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.jem.workbench_1.2.0.v20060530_RC2.jar[~org/eclipse/jem/internal/adapters/jdom/*;~org/eclipse/jem/internal/plugin/*;+org/eclipse/jem/workbench/utility/*;?**/*] diff --git a/com.ibm.wala.j2ee/lib/extension.jar.model b/com.ibm.wala.j2ee/lib/extension.jar.model new file mode 100644 index 000000000..c3727db15 Binary files /dev/null and b/com.ibm.wala.j2ee/lib/extension.jar.model differ diff --git a/com.ibm.wala.j2ee/plugin.properties b/com.ibm.wala.j2ee/plugin.properties new file mode 100644 index 000000000..1492814fe --- /dev/null +++ b/com.ibm.wala.j2ee/plugin.properties @@ -0,0 +1,2 @@ +PLUGINNAME=WALA J2EE support +VENDORNAME=IBM \ No newline at end of file diff --git a/com.ibm.wala.j2ee/src/com/ibm/wala/j2ee/AbstractDeclaredTransaction.java b/com.ibm.wala.j2ee/src/com/ibm/wala/j2ee/AbstractDeclaredTransaction.java new file mode 100644 index 000000000..d10d9583a --- /dev/null +++ b/com.ibm.wala.j2ee/src/com/ibm/wala/j2ee/AbstractDeclaredTransaction.java @@ -0,0 +1,173 @@ +/******************************************************************************* + * 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.j2ee; + +import org.eclipse.jst.j2ee.ejb.EnterpriseBean; +import org.eclipse.jst.j2ee.ejb.MethodElement; +import org.eclipse.jst.j2ee.ejb.MethodElementKind; +import org.eclipse.jst.j2ee.ejb.TransactionAttributeType; + +import com.ibm.wala.types.MethodReference; +import com.ibm.wala.util.debug.Assertions; + +/** + * + * Represents a declarative transaction attribute, either from a deployment + * descriptor or synthetic + * + * @author sfink + */ +public abstract class AbstractDeclaredTransaction implements Comparable, IDeclaredTransaction { + + /** + * The governing entity bean. + */ + private final EnterpriseBean bean; + + /** + * A constant from MethodElementKind + */ + private int kind; + + /** + * A constant from TransactionAttributeType + */ + private int transactionType; + + public AbstractDeclaredTransaction(EnterpriseBean B, int kind, int transactionType) { + this.bean = B; + this.kind = kind; + this.transactionType = transactionType; + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#toString() + */ + public String toString() { + StringBuffer result = new StringBuffer(bean.getName() + ":" + kindString() + getMethodReference()); + result.append("\n "); + result.append(transactionTypeString()); + result.append("\n "); + + return result.toString(); + } + + private String transactionTypeString() { + switch (transactionType) { + case TransactionAttributeType.MANDATORY: + return "MANDATORY"; + case TransactionAttributeType.NEVER: + return "NEVER "; + case TransactionAttributeType.NOT_SUPPORTED: + return "NOT SUPPORTED "; + case TransactionAttributeType.REQUIRED: + return "REQUIRED "; + case TransactionAttributeType.REQUIRES_NEW: + return "REQUIRES NEW "; + case TransactionAttributeType.SUPPORTS: + return "SUPPORTS "; + default: + Assertions.UNREACHABLE(); + return null; + } + } + + private String kindString() { + switch (kind) { + case MethodElementKind.HOME: + return "Home Interface: "; + case MethodElementKind.REMOTE: + return "Remote Interface: "; + case MethodElementKind.LOCAL: + return "Local Interface: "; + case MethodElementKind.LOCAL_HOME: + return "LocalHome Interface: "; + case MethodElementKind.UNSPECIFIED: + return "Unspecified Interface: "; + default: + Assertions.UNREACHABLE(); + return null; + } + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#equals(java.lang.Object) + */ + public boolean equals(Object obj) { + if (this.getClass() != obj.getClass()) + return false; + AbstractDeclaredTransaction other = (AbstractDeclaredTransaction) obj; + return (bean.equals(other.bean) && getMethodReference().equals(other.getMethodReference()) && kind == other.kind); + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#hashCode() + */ + public int hashCode() { + return bean.hashCode() * 93 + kind * 5 + getMethodReference().hashCode(); + } + + /* + * (non-Javadoc) + * + * @see java.lang.Comparable#compareTo(java.lang.Object) + */ + public int compareTo(IDeclaredTransaction o) { + if (Assertions.verifyAssertions) { + Assertions._assert(this.getClass().equals(o.getClass())); + } + String A = bean.toString() + kindString() + getMethodReference().toString(); + AbstractDeclaredTransaction other = (AbstractDeclaredTransaction) o; + String B = other.bean.toString() + other.kindString() + other.getMethodReference().toString(); + return A.compareTo(B); + } + + /** + * TODO: cache this? + */ + public abstract MethodReference getMethodReference(); + + public boolean isRequired() { + return transactionType == TransactionAttributeType.REQUIRED; + } + + public boolean isRequiresNew() { + return transactionType == TransactionAttributeType.REQUIRES_NEW; + } + + public boolean isNotSupported() { + return transactionType == TransactionAttributeType.NOT_SUPPORTED; + } + + public boolean isNever() { + return transactionType == TransactionAttributeType.NEVER; + } + + public boolean isMandatory() { + return transactionType == TransactionAttributeType.MANDATORY; + } + + public boolean isSupports() { + return transactionType == TransactionAttributeType.SUPPORTS; + } + + public EnterpriseBean getBean() { + return bean; + } + + public abstract MethodElement getMethodElement(); +} diff --git a/com.ibm.wala.j2ee/src/com/ibm/wala/j2ee/AppClientEntrypoints.java b/com.ibm.wala.j2ee/src/com/ibm/wala/j2ee/AppClientEntrypoints.java new file mode 100644 index 000000000..044ce82c5 --- /dev/null +++ b/com.ibm.wala.j2ee/src/com/ibm/wala/j2ee/AppClientEntrypoints.java @@ -0,0 +1,166 @@ +/******************************************************************************* + * 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.j2ee; + +import java.util.HashMap; +import java.util.Iterator; + +import org.eclipse.jst.j2ee.commonarchivecore.internal.ApplicationClientFile; +import org.eclipse.jst.j2ee.commonarchivecore.internal.helpers.ArchiveManifest; + +import com.ibm.wala.classLoader.IClass; +import com.ibm.wala.classLoader.IMethod; +import com.ibm.wala.classLoader.Module; +import com.ibm.wala.classLoader.ModuleEntry; +import com.ibm.wala.ipa.callgraph.AnalysisScope; +import com.ibm.wala.ipa.callgraph.Entrypoint; +import com.ibm.wala.ipa.callgraph.Entrypoints; +import com.ibm.wala.ipa.callgraph.impl.DefaultEntrypoint; +import com.ibm.wala.ipa.cha.ClassHierarchy; +import com.ibm.wala.j2ee.util.TopLevelArchiveModule; +import com.ibm.wala.types.ClassLoaderReference; +import com.ibm.wala.types.Descriptor; +import com.ibm.wala.types.MethodReference; +import com.ibm.wala.types.TypeName; +import com.ibm.wala.types.TypeReference; +import com.ibm.wala.util.Atom; +import com.ibm.wala.util.collections.HashMapFactory; +import com.ibm.wala.util.debug.Trace; +import com.ibm.wala.util.warnings.WarningSet; + +/** + * + * Representation of entrypoints gleaned from the descriptor for an + * ApplicationClient module. + * + * @author sfink + */ +public class AppClientEntrypoints implements Entrypoints { + + static final boolean DEBUG = false; + + /** + * Map: MethodReference -> Entrypoint + */ + private HashMap entrypoints = HashMapFactory.make(); + + /** + * Governing class hierarchy + */ + private final ClassHierarchy cha; + + /** + * Governing analysis scope + */ + private final AnalysisScope scope; + + private final WarningSet warnings; + + /** + * Constructor. + * + * @param scope + * scope of analysis + * @param cha + * loaded class hierarchy + */ + public AppClientEntrypoints(J2EEAnalysisScope scope, ClassHierarchy cha, WarningSet warnings) { + this.cha = cha; + this.scope = scope; + this.warnings = warnings; + ClassLoaderReference loader = scope.getApplicationLoader(); + for (Iterator it = scope.getModules(loader).iterator(); it.hasNext();) { + Module M = (Module) it.next(); + if (M instanceof TopLevelArchiveModule) { + addEntrypointsRecursive((TopLevelArchiveModule) M, loader); + } + } + } + + /** + * Recursively traverse a module and add entrypoints from ApplicationClient + * archives + * + * @param T + * a WCCM archive + * @param loader + * governing class loader + */ + @SuppressWarnings("restriction") + private void addEntrypointsRecursive(TopLevelArchiveModule T, ClassLoaderReference loader) { + if (T.getType() == TopLevelArchiveModule.APPLICATION_CLIENT_FILE) { + addEntrypoints((ApplicationClientFile) T.materializeArchive()); + } else { + for (Iterator it = T.getEntries(); it.hasNext();) { + ModuleEntry E = (ModuleEntry) it.next(); + if (E.isModuleFile()) { + Module M = E.asModule(); + if (M instanceof TopLevelArchiveModule) { + addEntrypointsRecursive((TopLevelArchiveModule) M, loader); + } + } + } + } + } + + /** + * @param file + */ + @SuppressWarnings("restriction") + private void addEntrypoints(ApplicationClientFile file) { + ArchiveManifest manifest = file.getManifest(); + String mainClass = manifest.getMainClass(); + if (DEBUG) { + Trace.println("AppClientEntrypoints: add for file " + file); + } + if (mainClass == null) { + if (DEBUG) { + Trace.println("AppClientEntrypoints:WARNING: mainClass is null"); + } + return; + } + final Atom mainMethod = Atom.findOrCreateAsciiAtom("main"); + TypeName mainName = TypeName.string2TypeName("L" + mainClass.replace('.', '/')); + final TypeReference T = TypeReference.findOrCreate(scope.getApplicationLoader(), mainName); + final MethodReference Main = MethodReference.findOrCreate(T, mainMethod, Descriptor.findOrCreateUTF8("([Ljava/lang/String;)V")); + if (DEBUG) { + Trace.println("AppClientEntrypoints: create entrypoint " + Main); + } + IClass klass = cha.lookupClass(T); + if (klass == null) { + warnings.add(LoadFailure.create(T)); + return; + } + IMethod m = cha.resolveMethod(klass,Main.getSelector()); + if (m == null) { + warnings.add(LoadFailure.create(Main)); + return; + } + entrypoints.put(Main, new DefaultEntrypoint(m, cha)); + } + /* + * (non-Javadoc) + * + * @see com.ibm.wala.ipa.callgraph.Entrypoints#iterator() + */ + public Iterator iterator() { + return entrypoints.values().iterator(); + } + + /** + * @param m + * @return true iff m is an entrypoint recorded by this class + */ + public boolean contains(MethodReference m) { + return entrypoints.keySet().contains(m); + } + +} diff --git a/com.ibm.wala.j2ee/src/com/ibm/wala/j2ee/BeanMetaData.java b/com.ibm.wala.j2ee/src/com/ibm/wala/j2ee/BeanMetaData.java new file mode 100644 index 000000000..57e2cc7b7 --- /dev/null +++ b/com.ibm.wala.j2ee/src/com/ibm/wala/j2ee/BeanMetaData.java @@ -0,0 +1,174 @@ +/******************************************************************************* + * 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.j2ee; + +import java.util.Collection; +import java.util.Map; +import java.util.Set; + +import org.eclipse.jst.j2ee.ejb.CMRField; +import org.eclipse.jst.j2ee.ejb.EJBJar; +import org.eclipse.jst.j2ee.ejb.EnterpriseBean; + +import com.ibm.wala.types.FieldReference; +import com.ibm.wala.types.MethodReference; +import com.ibm.wala.types.TypeReference; + +/** + * + * Deployment descriptor data for a single EJB. + * + * TODO: this currently can represent either a session or entity bean. Introduce + * classes to distinguish between them. + * + * @author sfink + */ +public interface BeanMetaData { + + /** + * Return a Set of IFields, one corresponding to each CMP field in this bean. + * + * @return Set of IFields + */ + Collection getCMPFields(); + + /** + * Return a Set of container managed relationship (cmr) fields, as + * FieldReference objects. + * + * @return Set of cmrs + */ + Set getCMRFields(); + + /** + * Return a Map of the container created getter methods, as MethodReference + * objects, and the field that the method references. + * + * @return Map of container created getter methods and field reference. + */ + Map getGetterMethods(); + + /** + * Return a Map of the container created setter methods, as MethodReference + * objects, and the field that the method references. + * + * @return Map of container created setter methods and field reference. + */ + Map getSetterMethods(); + + /** + * Return a Map of container created getter methods for CMRs, as a mapping + * from MethodReference->FieldReference. The container is responsible for + * creating a getter method for each container managed relationship. + */ + Map getCMRGetters(); + + /** + * Return a Map of container created setter methods for CMRs, as a mapping + * from MethodReference->FieldReference. The container is responsible for + * creating a setter method for each container managed relationship. + */ + Map getCMRSetters(); + + /** + * Return the type of the EJB class for this entity bean + * + * @return TypeReference + */ + TypeReference getEJBClass(); + + /** + * Return true if the bean is container managed. + * + * @return true if bean is container manged. + */ + boolean isContainerManaged(); + + /** + * Return true if the bean is a container managed entity. + * + * @return true if bean is a container manged entity. + */ + boolean isContainerManagedEntity(); + + /** + * Return true if the bean uses BMP + * + * @return true if bean uses BMP + */ + boolean isBeanManaged(); + + /** + * Return true if the bean is a session bean. + * + * @return true if bean is a session bean. + */ + boolean isSessionBean(); + + /** + * Return true if the bean is a message-driven + * + * @return true if bean is a message-driven + */ + boolean isMessageDrivenBean(); + + /** + * Return the Set of container created finder methods, as Method reference + * objects. + * + * @return Set of container created setter methods. + */ + public Set getFinders(); + + /** + * Method getField. + * + * @param firstField + * @return FieldReference + */ + FieldReference getField(CMRField firstField); + + /** + * @return WCCM representation of this bean. + */ + public EnterpriseBean getBean(); + + /** + * @return WCCM representation of this bean's container + */ + EJBJar getEJBJar(); + + /** + * @return TypeReference representing this entity's home interface + */ + TypeReference getHomeInterface(); + + /** + * @return TypeReference representing this entity's local home interface + */ + TypeReference getLocalHomeInterface(); + + /** + * @return TypeReference representing this entity's remote interface + */ + TypeReference getRemoteInterface(); + + /** + * @return TypeReference representing this entity's local interface + */ + TypeReference getLocalInterface(); + + /** + * @return TypeReference representing this entity's primary key type. + */ + TypeReference getPrimaryKeyType(); + +} \ No newline at end of file diff --git a/com.ibm.wala.j2ee/src/com/ibm/wala/j2ee/BeanMetaDataImpl.java b/com.ibm.wala.j2ee/src/com/ibm/wala/j2ee/BeanMetaDataImpl.java new file mode 100644 index 000000000..f9ad03c9c --- /dev/null +++ b/com.ibm.wala.j2ee/src/com/ibm/wala/j2ee/BeanMetaDataImpl.java @@ -0,0 +1,531 @@ +/******************************************************************************* + * 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.j2ee; + +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.eclipse.jem.java.JavaClass; +import org.eclipse.jem.java.Method; +import org.eclipse.jst.j2ee.ejb.CMPAttribute; +import org.eclipse.jst.j2ee.ejb.CMRField; +import org.eclipse.jst.j2ee.ejb.ContainerManagedEntity; +import org.eclipse.jst.j2ee.ejb.EJBJar; +import org.eclipse.jst.j2ee.ejb.EnterpriseBean; +import org.eclipse.jst.j2ee.ejb.Entity; +import org.eclipse.jst.j2ee.ejb.Session; +import org.eclipse.jst.j2ee.ejb.TransactionType; + +import com.ibm.wala.types.Descriptor; +import com.ibm.wala.types.FieldReference; +import com.ibm.wala.types.MethodReference; +import com.ibm.wala.types.TypeName; +import com.ibm.wala.types.TypeReference; +import com.ibm.wala.util.Atom; +import com.ibm.wala.util.StringStuff; +import com.ibm.wala.util.collections.HashMapFactory; +import com.ibm.wala.util.collections.HashSetFactory; +import com.ibm.wala.util.debug.Assertions; + +/** + * + * Simple implementation of the BeanMetaData interface. + * + * TODO: rework this class to have a hierarchy to distinguish between entities and + * other beans. + * + * @author sfink + */ +public class BeanMetaDataImpl implements BeanMetaData { + + /** + * Meta-data describing this enterprise bean + */ + private final EnterpriseBean bean; + + /** + * Meta-data describing this enterprise bean's conatiner + */ + private final EJBJar ejbJar; + + /** + * Reference to Java class information for this bean + */ + private final TypeReference klass; + + /** + * Reference to home interface type + */ + private TypeReference homeInterface; + + /** + * Reference to local home interface type + */ + private TypeReference localHomeInterface; + + /** + * Reference to remote interface type + */ + private TypeReference remoteInterface; + + /** + * Reference to local interface type + */ + private TypeReference localInterface; + + /** + * Mapping from field name (Atom) to FieldReference for all + * CMP fields in this bean. + */ + private Map cmpFields; + + /** + * Constructor BeanMetaDataImpl. + * @param b + */ + BeanMetaDataImpl(EnterpriseBean b, EJBJar ejbJar, TypeReference cl) { + this.bean = b; + this.klass = cl; + this.ejbJar = ejbJar; + computeEJBInterfaces(); + computeCMPFields(); + } + + /** + * initialized the cached references to EJB interfaces for this bean. + */ + private void computeEJBInterfaces() { + String homeName = bean.getHomeInterfaceName(); + if (homeName != null) { + homeInterface = J2EEUtil.getTypeForInterface(klass.getClassLoader(), homeName); + } + + String localHomeName = bean.getLocalHomeInterfaceName(); + if (localHomeName != null) { + localHomeInterface = J2EEUtil.getTypeForInterface(klass.getClassLoader(), localHomeName); + } + + String remoteName = bean.getRemoteInterfaceName(); + if (remoteName != null) { + remoteInterface = J2EEUtil.getTypeForInterface(klass.getClassLoader(), remoteName); + } + + String localName = bean.getLocalInterfaceName(); + if (localName != null) { + localInterface = J2EEUtil.getTypeForInterface(klass.getClassLoader(), localName); + } + } + + /** + * compute a Set of FieldReferences, one corresponding to each + * CMP field in this bean. + */ + private void computeCMPFields() { + cmpFields = Collections.emptyMap(); + if (bean instanceof ContainerManagedEntity) { + ContainerManagedEntity cme = (ContainerManagedEntity) bean; + cmpFields = HashMapFactory.make(3); + addCMPAttributes(cme); + } + } + + @SuppressWarnings("unchecked") + private void addCMPAttributes(ContainerManagedEntity cme) { + List CMPFields = cme.getPersistentAttributes(); + for (Iterator it = CMPFields.iterator(); it.hasNext();) { + CMPAttribute att = (CMPAttribute) it.next(); + if (att.getType() == null) { + System.err.println("PANIC: null type in attribute: " + att); + continue; + } + FieldReference f = createFieldReference(att); + cmpFields.put(f.getName(), f); + } + for (Iterator cmrField = cme.getCMRFields().iterator(); cmrField.hasNext();) { + CMRField cmr = (CMRField) cmrField.next(); + if (cmr.getType() == null) { + System.err.println("PANIC: null type in attribute: " + cmr); + continue; + } + FieldReference f = createFieldReference(cmr); + cmpFields.put(f.getName(), f); + } + } + /** + * Return a Set of FieldReferences, one corresponding to each + * CMP field in this bean. + */ + public Collection getCMPFields() { + return cmpFields.values(); + } + + /** + * Return a Set of the bean's container managed relationship fields, + * as FieldReference objects. + * @return the bean's CMRs. + */ + @SuppressWarnings("unchecked") + public Set getCMRFields() { + Set result = Collections.emptySet(); + if (bean instanceof ContainerManagedEntity) { + ContainerManagedEntity entity = (ContainerManagedEntity) bean; + result = HashSetFactory.make(3); + for (Iterator cmrField = entity.getCMRFields().iterator(); cmrField.hasNext();) { + CMRField cmr = (CMRField) cmrField.next(); + if (cmr.getType() == null) { + System.err.println("PANIC: null attribute type for " + cmr); + continue; + } + FieldReference f = createFieldReference(cmr); + result.add(f); + } + } + return result; + } + + /** + * Return the Set of container created getter methods, as + * MethodReference objects. The container is responsible for creating + * a getter method for each container managed field and relationship. + * @see com.ibm.wala.j2ee.BeanMetaData#getGetterMethods() + * @return Set of container created getter methods. + */ + @SuppressWarnings("unchecked") + public Map getGetterMethods() { + Map result = Collections.emptyMap(); + if (bean instanceof ContainerManagedEntity) { + ContainerManagedEntity cme = (ContainerManagedEntity) bean; + result = HashMapFactory.make(3); + for (Iterator cmpFields = cme.getPersistentAttributes().iterator(); cmpFields.hasNext();) { + CMPAttribute attr = (CMPAttribute) cmpFields.next(); + if (attr.getType() == null) { + System.err.println("PANIC: null type in attribute: " + attr); + continue; + } + MethodReference m = createGetterReference(attr, attr.getGetterName()); + FieldReference f = createFieldReference(attr); + result.put(m, f); + } + for (Iterator cmrFields = cme.getCMRFields().iterator(); cmrFields.hasNext();) { + CMPAttribute attr = (CMPAttribute) cmrFields.next(); + if (attr.getType() == null) { + System.err.println("PANIC: null type in attribute: " + attr); + continue; + } + MethodReference m = createGetterReference(attr, attr.getGetterName()); + FieldReference f = createFieldReference(attr); + result.put(m, f); + } + } + return result; + } + /** + * Return the Set of container created getter methods for CMRs, as + * a mapping from MethodReference->FieldReference. The container is responsible for creating + * a getter method for each container managed relationship. + */ + @SuppressWarnings("unchecked") + public Map getCMRGetters() { + Map result = Collections.emptyMap(); + if (bean instanceof ContainerManagedEntity) { + ContainerManagedEntity cme = (ContainerManagedEntity) bean; + result = HashMapFactory.make(3); + for (Iterator cmrFields = cme.getCMRFields().iterator(); cmrFields.hasNext();) { + CMPAttribute attr = (CMPAttribute) cmrFields.next(); + if (attr.getType() == null) { + System.err.println("PANIC: null type in attribute: " + attr); + continue; + } + MethodReference m = createGetterReference(attr, attr.getGetterName()); + FieldReference f = createFieldReference(attr); + result.put(m, f); + } + } + return result; + } + /** + * Return the Set of container created setter methods, as + * Method reference objects. The container is responsible for creating + * a setter method for each container managed field or relationship. + * @see com.ibm.wala.j2ee.BeanMetaData#getSetterMethods() + * @return Set of container created setter methods. + */ + @SuppressWarnings("unchecked") + public Map getSetterMethods() { + Map result = Collections.emptyMap(); + if (bean instanceof ContainerManagedEntity) { + ContainerManagedEntity cme = (ContainerManagedEntity) bean; + result = HashMapFactory.make(3); + for (Iterator cmpFields = cme.getPersistentAttributes().iterator(); cmpFields.hasNext();) { + CMPAttribute attr = (CMPAttribute) cmpFields.next(); + if (attr.getType() == null) { + System.err.println("PANIC: null type in attribute: " + attr); + continue; + } + MethodReference m = createSetterReference(attr, attr.getSetterName()); + FieldReference f = createFieldReference(attr); + result.put(m, f); + } + for (Iterator cmrFields = cme.getCMRFields().iterator(); cmrFields.hasNext();) { + CMPAttribute attr = (CMPAttribute) cmrFields.next(); + if (attr.getType() == null) { + System.err.println("PANIC: null type in attribute: " + attr); + continue; + } + MethodReference m = createSetterReference(attr, attr.getSetterName()); + FieldReference f = createFieldReference(attr); + result.put(m, f); + } + } + return result; + } + + /** + * Return the Set of container created setter methods for CMRs, as + * a mapping from MethodReference->FieldReference. The container is responsible for creating + * a setter method for each container managed relationship. + */ + @SuppressWarnings("unchecked") + public Map getCMRSetters() { + Map result = Collections.emptyMap(); + if (bean instanceof ContainerManagedEntity) { + ContainerManagedEntity cme = (ContainerManagedEntity) bean; + result = HashMapFactory.make(3); + for (Iterator cmrFields = cme.getCMRFields().iterator(); cmrFields.hasNext();) { + CMPAttribute attr = (CMPAttribute) cmrFields.next(); + if (attr.getType() == null) { + System.err.println("PANIC: null type in attribute: " + attr); + continue; + } + MethodReference m = createSetterReference(attr, attr.getSetterName()); + FieldReference f = createFieldReference(attr); + result.put(m, f); + } + } + return result; + } + /** + * Return the Set of container created finder methods, as + * Method reference objects. + */ + public Set getFinders() { + HashSet result = HashSetFactory.make(5); + Method[] methods = bean.getLocalHomeMethodsForDeployment(); + extractFinders(result, methods); + methods = bean.getHomeMethodsForDeployment(); + extractFinders(result, methods); + return result; + } + + private void extractFinders(HashSet result, Method[] methods) { + for (int i = 0; i < methods.length; i++) { + Method method = methods[i]; + if (isFinder(method)) { + MethodReference ref = createMethodReference(method); + result.add(ref); + } + } + } + + /** + * Method isFinder. + * @param method + * @return boolean + */ + private static boolean isFinder(Method method) { + return method.getName().indexOf("find") == 0; + } + + /** + * Create a field reference from a container managed field attribute. + * @param att the container managed field attribute + * @return FieldReference + */ + private FieldReference createFieldReference(CMPAttribute att) { + if (Assertions.verifyAssertions) { + Assertions._assert(att != null, "null attribute"); + Assertions._assert(att.getType() != null, "null attribute type"); + } + Atom name = Atom.findOrCreateUnicodeAtom(att.getName()); + String dString = att.getType().getJavaName(); + dString = StringStuff.deployment2CanonicalTypeString(dString); + TypeReference fieldType = TypeReference.findOrCreate(klass.getClassLoader(), TypeName.string2TypeName(dString)); + FieldReference f = FieldReference.findOrCreate(klass, name, fieldType); + return f; + } + + /** + * Create a method reference from a finder + * @param method etools method representation + * @return MethodReference that represents the method. + */ + private MethodReference createMethodReference(Method method) { + return J2EEUtil.createMethodReference(method, klass.getClassLoader()); + } + /** + * Create a method reference from a container managed field attribute. + * @param attr the container managed field attribute + * @param methodName the name of the method + * @return MethodReference that represents the method. + */ + private MethodReference createGetterReference(CMPAttribute attr, String methodName) { + String ret = StringStuff.deployment2CanonicalDescriptorTypeString(attr.getType().getJavaName()); + Descriptor D = Descriptor.findOrCreateUTF8("()" + ret); + Atom name = Atom.findOrCreateUnicodeAtom(methodName); + MethodReference m = MethodReference.findOrCreate(klass, name, D); + return m; + } + /** + * Create a method reference from a container managed field attribute. + * @param attr the container managed field attribute + * @param methodName the name of the method + * @return MethodReference that represents the method. + */ + private MethodReference createSetterReference(CMPAttribute attr, String methodName) { + String arg = StringStuff.deployment2CanonicalDescriptorTypeString(attr.getType().getJavaName()); + Atom name = Atom.findOrCreateUnicodeAtom(methodName); + Descriptor D = Descriptor.findOrCreateUTF8("(" + arg + ")V"); + MethodReference m = MethodReference.findOrCreate(klass, name, D); + return m; + } + + /** + * @see com.ibm.wala.j2ee.BeanMetaData#getEJBClass() + */ + public TypeReference getEJBClass() { + return klass; + } + + /* + * @see com.ibm.wala.j2ee.BeanMetaData#isContainerManaged() + */ + public boolean isContainerManaged() { + if (bean.isContainerManagedEntity()) + return true; + else if (bean.isSession()) { + Session s = (Session) bean; + if (s.getTransactionType() != null) { + TransactionType t = s.getTransactionType(); + if (t.getValue() == TransactionType.CONTAINER) { + return true; + } + } + } + return false; + } + + /* + * @see com.ibm.wala.j2ee.BeanMetaData#isContainerManaged() + */ + public boolean isContainerManagedEntity() { + return bean.isContainerManagedEntity(); + } + + /* (non-Javadoc) + * @see com.ibm.wala.j2ee.BeanMetaData#isSessionBean() + */ + public boolean isSessionBean() { + return bean.isSession(); + } + + /* (non-Javadoc) + * @see com.ibm.wala.j2ee.BeanMetaData#isMessageDrivenBean() + */ + public boolean isMessageDrivenBean() { + return bean.isMessageDriven(); + } + + /** + * @see com.ibm.wala.j2ee.BeanMetaData#getField(CMRField) + */ + public FieldReference getField(CMRField field) { + Atom name = Atom.findOrCreateUnicodeAtom(field.getName()); + return cmpFields.get(name); + } + + /** + * @see java.lang.Object#toString() + */ + public String toString() { + return klass.toString(); + } + + /** + * @return wccm model of this bean + */ + public EnterpriseBean getBean() { + return bean; + } + + /* (non-Javadoc) + * @see com.ibm.wala.j2ee.BeanMetaData#getHomeInterface() + */ + public TypeReference getHomeInterface() { + return homeInterface; + } + + /* (non-Javadoc) + * @see com.ibm.wala.j2ee.BeanMetaData#getLocalHomeInterface() + */ + public TypeReference getLocalHomeInterface() { + return localHomeInterface; + } + + /* (non-Javadoc) + * @see com.ibm.wala.j2ee.BeanMetaData#getRemoteInterface() + */ + public TypeReference getRemoteInterface() { + return remoteInterface; + } + + /* (non-Javadoc) + * @see com.ibm.wala.j2ee.BeanMetaData#getLocalInterface() + */ + public TypeReference getLocalInterface() { + return localInterface; + } + + public TypeReference getPrimaryKeyType() { + if (bean instanceof Entity) { + JavaClass keyKlass = ((Entity) bean).getPrimaryKey(); + String name = keyKlass.getQualifiedNameForReflection(); + return J2EEUtil.getTypeForInterface(klass.getClassLoader(), name); + } else { + return null; + } + } + + /* (non-Javadoc) + * @see com.ibm.wala.j2ee.BeanMetaData#isBeanManaged() + */ + public boolean isBeanManaged() { + return bean.isBeanManagedEntity(); + } + + /* (non-Javadoc) + * @see com.ibm.wala.j2ee.BeanMetaData#getEJBJar() + */ + public EJBJar getEJBJar() { + return ejbJar; + } + /* (non-Javadoc) + * @see java.lang.Object#hashCode() + */ + public int hashCode() { + return bean.hashCode() * 941; + } + +} diff --git a/com.ibm.wala.j2ee/src/com/ibm/wala/j2ee/CommandInterpreter.java b/com.ibm.wala.j2ee/src/com/ibm/wala/j2ee/CommandInterpreter.java new file mode 100644 index 000000000..c3ceba5cf --- /dev/null +++ b/com.ibm.wala.j2ee/src/com/ibm/wala/j2ee/CommandInterpreter.java @@ -0,0 +1,435 @@ +/******************************************************************************* + * 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.j2ee; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import com.ibm.wala.analysis.reflection.JavaTypeContext; +import com.ibm.wala.analysis.typeInference.ConeType; +import com.ibm.wala.analysis.typeInference.PointType; +import com.ibm.wala.analysis.typeInference.TypeAbstraction; +import com.ibm.wala.cfg.ControlFlowGraph; +import com.ibm.wala.cfg.InducedCFG; +import com.ibm.wala.classLoader.CallSiteReference; +import com.ibm.wala.classLoader.IClass; +import com.ibm.wala.classLoader.IField; +import com.ibm.wala.classLoader.IMethod; +import com.ibm.wala.classLoader.NewSiteReference; +import com.ibm.wala.classLoader.SyntheticMethod; +import com.ibm.wala.ipa.callgraph.CGNode; +import com.ibm.wala.ipa.callgraph.Context; +import com.ibm.wala.ipa.callgraph.ContextKey; +import com.ibm.wala.ipa.callgraph.impl.Everywhere; +import com.ibm.wala.ipa.callgraph.propagation.SSAContextInterpreter; +import com.ibm.wala.ipa.cha.ClassHierarchy; +import com.ibm.wala.ipa.summaries.SyntheticIR; +import com.ibm.wala.shrikeBT.IInvokeInstruction; +import com.ibm.wala.ssa.DefUse; +import com.ibm.wala.ssa.IR; +import com.ibm.wala.ssa.SSAInstruction; +import com.ibm.wala.ssa.SSAInvokeInstruction; +import com.ibm.wala.ssa.SSAOptions; +import com.ibm.wala.types.Descriptor; +import com.ibm.wala.types.MethodReference; +import com.ibm.wala.types.TypeReference; +import com.ibm.wala.util.Atom; +import com.ibm.wala.util.collections.EmptyIterator; +import com.ibm.wala.util.collections.HashMapFactory; +import com.ibm.wala.util.debug.Assertions; +import com.ibm.wala.util.debug.Trace; +import com.ibm.wala.util.warnings.Warning; +import com.ibm.wala.util.warnings.WarningSet; + +/** + * + * Logic to interpret dynacache commands in context + * + * @author sfink + */ +public class CommandInterpreter implements SSAContextInterpreter { + + private static final boolean DEBUG = false; + + private static final Atom PerformExecuteAtom = Atom.findOrCreateAsciiAtom("performExecute"); + private final static Descriptor PerformExecuteDesc = Descriptor.findOrCreateUTF8("()V"); + + /** + * A cache of synthetic method implementations, indexed by Context + */ + private final Map syntheticMethodCache = HashMapFactory.make(); + + /** + * Governing class hierarchy + */ + private final ClassHierarchy cha; + + /** + * Keep track of analysis warnings + */ + private WarningSet warnings; + + /** + * @param cha + * governing class hierarchy + * @param warnings + * object to track analysis warnings + */ + public CommandInterpreter(ClassHierarchy cha, WarningSet warnings) { + this.cha = cha; + this.warnings = warnings; + } + + /* + * (non-Javadoc) + * + * @see com.ibm.wala.ipa.callgraph.propagation.cfa.CFAContextInterpreter#getIR(com.ibm.wala.classLoader.IMethod, + * com.ibm.wala.ipa.callgraph.Context, + * com.ibm.wala.util.warnings.WarningSet) + */ + public IR getIR(CGNode node, WarningSet warnings) { + SpecializedExecuteMethod m = findOrCreateSpecializedMethod(node); + return m.getIR(warnings); + } + + /* + * (non-Javadoc) + * + * @see com.ibm.wala.ipa.callgraph.propagation.cfa.CFAContextInterpreter#getNumberOfStatements(com.ibm.wala.classLoader.IMethod, + * com.ibm.wala.ipa.callgraph.Context, + * com.ibm.wala.util.warnings.WarningSet) + */ + public int getNumberOfStatements(CGNode node, WarningSet warnings) { + SpecializedExecuteMethod m = findOrCreateSpecializedMethod(node); + return m.calls.size(); + } + + /* + * (non-Javadoc) + * + * @see com.ibm.wala.ipa.callgraph.rta.RTAContextInterpreter#understands(com.ibm.wala.classLoader.IMethod, + * com.ibm.wala.ipa.callgraph.Context) + */ + public boolean understands(CGNode node) { + + if (!(node.getContext() instanceof JavaTypeContext)) { + return false; + } + return node.getMethod().getReference().equals(J2EEContextSelector.ExecuteMethod); + } + + /* + * (non-Javadoc) + * + * @see com.ibm.wala.ipa.callgraph.rta.RTAContextInterpreter#getNewSites(com.ibm.wala.classLoader.IMethod, + * com.ibm.wala.ipa.callgraph.Context, + * com.ibm.wala.util.warnings.WarningSet) + */ + public Iterator iterateNewSites(CGNode node, WarningSet warnings) { + return EmptyIterator.instance(); + } + + /** + * Evaluate a new-instance method in a given Context + */ + public Iterator getInvokeStatements(CGNode node) { + SpecializedExecuteMethod m = findOrCreateSpecializedMethod(node); + return m.getInvokeStatements().iterator(); + } + + /* + * (non-Javadoc) + * + * @see com.ibm.wala.ipa.rta.RTAContextInterpreter#getCallSites(com.ibm.wala.classLoader.IMethod, + * com.ibm.detox.ipa.callgraph.Context, + * com.ibm.wala.util.warnings.WarningSet) + */ + public Iterator iterateCallSites(CGNode node, WarningSet warnings) { + final Iterator I = getInvokeStatements(node); + return new Iterator() { + public boolean hasNext() { + return I.hasNext(); + } + + public CallSiteReference next() { + SSAInvokeInstruction s = (SSAInvokeInstruction) I.next(); + return s.getCallSite(); + } + + public void remove() { + Assertions.UNREACHABLE(); + } + }; + } + protected class SpecializedExecuteMethod extends SyntheticMethod { + + /** + * List of synthetic invoke instructions we model for this specialized + * instance. + */ + private ArrayList calls = new ArrayList(); + + int nextLocal = 2; + + private SpecializedExecuteMethod(IMethod execute, final TypeAbstraction T) { + super(execute, execute.getDeclaringClass(), false, false); + if (T instanceof PointType) { + addStatementsForConcreteType(T.getType().getReference()); + } else if (T instanceof ConeType) { + if (((ConeType) T).isInterface()) { + Set implementors = cha.getImplementors(T.getType().getReference()); + if (implementors.isEmpty()) { + if (DEBUG) { + Trace.println("Found no implementors of type " + T); + } + warnings.add(NoSubtypesWarning.create(T)); + } + + addStatementsForSetOfTypes(implementors.iterator()); + } else { + Collection subclasses = cha.computeSubClasses(T.getType().getReference()); + if (subclasses.isEmpty()) { + if (DEBUG) { + Trace.println("Found no subclasses of type " + T); + } + warnings.add(NoSubtypesWarning.create(T)); + } + addStatementsForSetOfTypes(subclasses.iterator()); + } + } else { + Assertions.UNREACHABLE("Unexpected type " + T.getClass()); + } + } + + /** + * Set up a method summary which allocates and returns an instance of + * concrete type T. + * + * @param T + */ + private void addStatementsForConcreteType(final TypeReference T) { + if (DEBUG) { + Trace.println("addStatementsForConcreteType: " + T); + } + MethodReference performExecute = MethodReference.findOrCreate(T, PerformExecuteAtom, PerformExecuteDesc); + CallSiteReference site = CallSiteReference.make(calls.size(), performExecute, IInvokeInstruction.Dispatch.VIRTUAL); + int[] params = new int[1]; + // value number 1 is the receiver. + params[0] = 1; + int exc = nextLocal++; + SSAInvokeInstruction s = new SSAInvokeInstruction(params, exc, site); + calls.add(s); + } + + private void addStatementsForSetOfTypes(Iterator it) { + for (; it.hasNext();) { + IClass klass = (IClass) it.next(); + TypeReference T = klass.getReference(); + addStatementsForConcreteType(T); + } + } + + /** + * @return List of InvokeInstruction + */ + public List getInvokeStatements() { + return calls; + } + + /** + * Two specialized methods can be different, even if they represent the same + * source method. So, revert to object identity for testing equality. TODO: + * this is non-optimal; could try to re-use specialized methods that have + * the same context. + * + * @see java.lang.Object#equals(java.lang.Object) + */ + public boolean equals(Object obj) { + return this == obj; + } + + /** + * Two specialized methods can be different, even if they represent the same + * source method. So, revert to object identity for testing equality. TODO: + * this is non-optimal; could try to re-use specialized methods that have + * the same context. + */ + public int hashCode() { + // TODO: change this to avoid non-determinism! + return System.identityHashCode(this); + } + + public String toString() { + return super.toString(); + } + + /* + * (non-Javadoc) + * + * @see com.ibm.wala.classLoader.IMethod#getStatements(com.ibm.wala.util.warnings.WarningSet) + */ + public SSAInstruction[] getStatements(WarningSet warnings) { + SSAInstruction[] result = new SSAInstruction[calls.size()]; + int i = 0; + for (Iterator it = calls.iterator(); it.hasNext();) { + result[i++] = it.next(); + } + return result; + } + + /* + * (non-Javadoc) + * + * @see com.ibm.wala.classLoader.IMethod#getIR(com.ibm.wala.util.warnings.WarningSet) + */ + public IR getIR(WarningSet warnings) { + SSAInstruction[] instrs = getStatements(warnings); + return new SyntheticIR(this, Everywhere.EVERYWHERE, new InducedCFG(instrs, this, Everywhere.EVERYWHERE), instrs, SSAOptions.defaultOptions(), null, warnings); + } + } + + /* + * (non-Javadoc) + * + * @see com.ibm.wala.ipa.callgraph.propagation.xta.XTAContextInterpreter#iterateFieldsRead(com.ibm.wala.ipa.callgraph.CGNode, + * com.ibm.wala.util.warnings.WarningSet) + */ + public Iterator iterateFieldsRead(CGNode node, WarningSet warnings) { + return EmptyIterator.instance(); + } + + /* + * (non-Javadoc) + * + * @see com.ibm.wala.ipa.callgraph.propagation.xta.XTAContextInterpreter#iterateFieldsWritten(com.ibm.wala.ipa.callgraph.CGNode, + * com.ibm.wala.util.warnings.WarningSet) + */ + public Iterator iterateFieldsWritten(CGNode node, WarningSet warnings) { + return EmptyIterator.instance(); + } + + /** + * @param node + * @return a synthetic method representing the node + */ + private SpecializedExecuteMethod findOrCreateSpecializedMethod(CGNode node) { + if (Assertions.verifyAssertions) { + if (!(node.getContext() instanceof JavaTypeContext)) + Assertions._assert(false, "unexpected context: " + node); + } + SpecializedExecuteMethod m = syntheticMethodCache.get(node.getContext()); + if (m == null) { + TypeAbstraction T = (TypeAbstraction) ((JavaTypeContext) node.getContext()).get(ContextKey.RECEIVER); + m = new SpecializedExecuteMethod(node.getMethod(), T); + syntheticMethodCache.put(node.getContext(), m); + } + return m; + } + + /* + * (non-Javadoc) + * + * @see com.ibm.wala.ipa.callgraph.propagation.xta.XTAContextInterpreter#getCaughtExceptions(com.ibm.wala.ipa.callgraph.CGNode, + * com.ibm.wala.util.warnings.WarningSet) + */ + public Set getCaughtExceptions(CGNode node, WarningSet warnings) { + return Collections.emptySet(); + } + + /* + * (non-Javadoc) + * + * @see com.ibm.wala.ipa.callgraph.propagation.xta.XTAContextInterpreter#hasObjectArrayLoad(com.ibm.wala.ipa.callgraph.CGNode, + * com.ibm.wala.util.warnings.WarningSet) + */ + public boolean hasObjectArrayLoad(CGNode node, WarningSet warnings) { + return false; + } + + /* + * (non-Javadoc) + * + * @see com.ibm.wala.ipa.callgraph.propagation.xta.XTAContextInterpreter#hasObjectArrayStore(com.ibm.wala.ipa.callgraph.CGNode, + * com.ibm.wala.util.warnings.WarningSet) + */ + public boolean hasObjectArrayStore(CGNode node, WarningSet warnings) { + return false; + } + + /* + * (non-Javadoc) + * + * @see com.ibm.wala.ipa.callgraph.propagation.xta.XTAContextInterpreter#iterateCastTypes(com.ibm.wala.ipa.callgraph.CGNode, + * com.ibm.wala.util.warnings.WarningSet) + */ + public Iterator iterateCastTypes(CGNode node, WarningSet warnings) { + return EmptyIterator.instance(); + } + + /* + * (non-Javadoc) + * + * @see com.ibm.wala.ipa.callgraph.rta.RTAContextInterpreter#recordFactoryType(com.ibm.wala.ipa.callgraph.CGNode, + * com.ibm.wala.classLoader.IClass) + */ + public boolean recordFactoryType(CGNode node, IClass klass) { + // this class does not observe factories + return false; + } + + /* + * (non-Javadoc) + * + * @see com.ibm.wala.ipa.callgraph.rta.RTAContextInterpreter#setWarnings(com.ibm.wala.util.warnings.WarningSet) + */ + public void setWarnings(WarningSet newWarnings) { + this.warnings = newWarnings; + } + + /* + * (non-Javadoc) + * + * @see com.ibm.wala.ipa.cfg.CFGProvider#getCFG(com.ibm.wala.ipa.callgraph.CGNode) + */ + public ControlFlowGraph getCFG(CGNode N, WarningSet warnings) { + return getIR(N, warnings).getControlFlowGraph(); + } + /** + * @author sfink + * + * A waring when we fail to find subtypes for a command method + */ + private static class NoSubtypesWarning extends Warning { + + final TypeAbstraction T; + NoSubtypesWarning(TypeAbstraction T) { + super(Warning.SEVERE); + this.T = T; + } + public String getMsg() { + return getClass().toString() + " : " + T; + } + public static NoSubtypesWarning create(TypeAbstraction T) { + return new NoSubtypesWarning(T); + } + } + /* (non-Javadoc) + * @see com.ibm.wala.ipa.callgraph.propagation.SSAContextInterpreter#getDU(com.ibm.wala.ipa.callgraph.CGNode, com.ibm.wala.util.warnings.WarningSet) + */ + public DefUse getDU(CGNode node, WarningSet warnings) { + return new DefUse(getIR(node,warnings)); + } +} diff --git a/com.ibm.wala.j2ee/src/com/ibm/wala/j2ee/DeploymentDeclaredTransaction.java b/com.ibm.wala.j2ee/src/com/ibm/wala/j2ee/DeploymentDeclaredTransaction.java new file mode 100644 index 000000000..1a117642c --- /dev/null +++ b/com.ibm.wala.j2ee/src/com/ibm/wala/j2ee/DeploymentDeclaredTransaction.java @@ -0,0 +1,68 @@ +/******************************************************************************* + * 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.j2ee; + +import org.eclipse.jem.java.Method; +import org.eclipse.jst.j2ee.ejb.EnterpriseBean; +import org.eclipse.jst.j2ee.ejb.MethodElement; + +import com.ibm.wala.types.ClassLoaderReference; +import com.ibm.wala.types.MethodReference; + +/** + * + * Represents a declarative transaction attribute in a deployment + * descriptor + * + * @author sfink + */ +public class DeploymentDeclaredTransaction extends AbstractDeclaredTransaction { + + /** + * The method whose call is declared to be a transaction + */ + private final Method method; + + /** + * The MethodElement that gave birth to this transaction + * declaration + */ + private final MethodElement methodElement; + + /** + * Reference to the governing class loader. + */ + private final ClassLoaderReference loader; + + /** + * @param method + */ + public DeploymentDeclaredTransaction(EnterpriseBean B, Method method, MethodElement methodElement, ClassLoaderReference loader, int kind, int transactionType) { + super(B,kind,transactionType); + this.method = method; + this.methodElement = methodElement; + this.loader = loader; + } + + /** + * TODO: cache this? + */ + public MethodReference getMethodReference() { + return J2EEUtil.createMethodReference(method, loader); + } + + public MethodElement getMethodElement() { + return methodElement; + } + + +} diff --git a/com.ibm.wala.j2ee/src/com/ibm/wala/j2ee/DeploymentMetaData.java b/com.ibm.wala.j2ee/src/com/ibm/wala/j2ee/DeploymentMetaData.java new file mode 100644 index 000000000..81227c13f --- /dev/null +++ b/com.ibm.wala.j2ee/src/com/ibm/wala/j2ee/DeploymentMetaData.java @@ -0,0 +1,199 @@ +/******************************************************************************* + * 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.j2ee; + +import java.util.Collection; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; + +import org.eclipse.jst.j2ee.ejb.EJBRelationshipRole; + +import com.ibm.wala.types.FieldReference; +import com.ibm.wala.types.MethodReference; +import com.ibm.wala.types.TypeReference; + +/** + * + * Interface to data from deployment descriptors. + * + * @author sfink + */ +public interface DeploymentMetaData { + + /** + * Return the BeanMetaData describing a particular bean, + * or null if the type does not correspond to an EJB. + * @param type TypeReference + */ + BeanMetaData getBeanMetaData(TypeReference type); + + /** + * Method getAllCMPFields. + * @return Set + */ + Set getAllCMPFields(); + + /** + * Return a Set of the container managed relationship (cmr) fields. + * @return Set of container managed relationship fields. + */ + Set getAllCMRFields(); + + /** + * Is a class an EJB remote interface? + */ + boolean isRemoteInterface(TypeReference t); + + /** + * Is a class an EJB home interface? + */ + boolean isHomeInterface(TypeReference t); + + /** + * Is a class an EJB local interface? + */ + boolean isLocalInterface(TypeReference t); + + /** + * Is a class an EJB local home interface? + */ + boolean isLocalHomeInterface(TypeReference t); + + /** + * Is a class an EJB interface (any flavor)? + */ + boolean isEJBInterface(TypeReference t); + + /** + * Is type an MDB? + */ + boolean isMessageDriven(TypeReference type); + + /** + * Return the entity bean implementation corresponding to + * the interface t + * + * @param t the home or remote interface for a bean + * @return the BeanMetaData, or null if not found. + */ + BeanMetaData getBeanForInterface(TypeReference t); + + /** + * Return true if the class is container managed. + * + * @return true if the class is container managed. + */ + boolean isContainerManaged(TypeReference t); + + /** + * Method getCMPType. + * @param typeReference + * @return TypeReference + */ + TypeReference getCMPType(TypeReference typeReference); + + /** + * Method isCMPGetter. + * @param mr + * @return boolean + */ + boolean isCMPGetter(MethodReference mr); + + /** + * Method getCMPField. + * @param mr + * @return the CMP Field the method gets or sets. + */ + FieldReference getCMPField(MethodReference mr); + + /** + * Method isCMPSetter. + * @param mr + * @return boolean + */ + boolean isCMPSetter(MethodReference mr); + + /** + * Return the Set of MethodReferences corresponding to EJB finder methods. + * @return Collection + */ + Collection getAllFinders(); + + /** + * Return the Set of methods corresponding to EJB CMR getter methods, + * as a mapping from MethodReference -> FieldReference + * @return Collection + */ + Map getAllCMRGetters(); + + /** + * Given a field that is populated by a CMR, return the descriptor + * of the Bean type that the field will point to. + * @param field + * @return BeanMetaData + */ + BeanMetaData getCMRBean(FieldReference field); + + /** + * @param method a finder + * @return the type representing the bean that is returned by this finder + */ + TypeReference getFinderBeanType(MethodReference method); + + /** + * @param ref + * @return true iff ref is finder method + */ + boolean isFinder(MethodReference ref); + + /** + * @return Iterator of all entity beans available + */ + Iterator iterateEntities(); + + /** + * @return Iterator of all session beans available + */ + Iterator iterateSessions(); + + /** + * @return Iterator of all message-driven beans available + */ + Iterator iterateMDBs(); + + /** + * @param method + * @return true iff method is a getter for a CMR. + */ + boolean isCMRGetter(MethodReference method); + + /** + * @param method + * @return true iff method is a setter for a CMR. + */ + boolean isCMRSetter(MethodReference method); + + /** + * @param field a field that represents a CMR + * @return the corresponding field on the opposite role of the CMR + */ + FieldReference getOppositeField(FieldReference field); + + /** + * @param field a field that represents a CMR + * @return the governing EJBRelationshipRole + */ + EJBRelationshipRole getCMRRole(FieldReference field); + + +} diff --git a/com.ibm.wala.j2ee/src/com/ibm/wala/j2ee/DeploymentMetaDataImpl.java b/com.ibm.wala.j2ee/src/com/ibm/wala/j2ee/DeploymentMetaDataImpl.java new file mode 100644 index 000000000..57fabc1e2 --- /dev/null +++ b/com.ibm.wala.j2ee/src/com/ibm/wala/j2ee/DeploymentMetaDataImpl.java @@ -0,0 +1,564 @@ +/******************************************************************************* + * 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.j2ee; + +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; + +import org.eclipse.jst.j2ee.commonarchivecore.internal.Archive; +import org.eclipse.jst.j2ee.commonarchivecore.internal.EARFile; +import org.eclipse.jst.j2ee.commonarchivecore.internal.EJBJarFile; +import org.eclipse.jst.j2ee.ejb.CMRField; +import org.eclipse.jst.j2ee.ejb.EJBJar; +import org.eclipse.jst.j2ee.ejb.EJBRelation; +import org.eclipse.jst.j2ee.ejb.EJBRelationshipRole; +import org.eclipse.jst.j2ee.ejb.EnterpriseBean; + +import com.ibm.wala.classLoader.Module; +import com.ibm.wala.ipa.callgraph.AnalysisScope; +import com.ibm.wala.types.ClassLoaderReference; +import com.ibm.wala.types.FieldReference; +import com.ibm.wala.types.MethodReference; +import com.ibm.wala.types.TypeReference; +import com.ibm.wala.util.collections.HashMapFactory; +import com.ibm.wala.util.collections.HashSetFactory; +import com.ibm.wala.util.debug.Assertions; +import com.ibm.wala.util.debug.Trace; + +/** + * + * A simple implementation of the DeploymentMetaData interface + * + * @author sfink + */ +public class DeploymentMetaDataImpl implements DeploymentMetaData { + + static final boolean DEBUG = false; + /** + * A mapping from type reference for a bean to the BeanMetaData object that + * describes the bean. + */ + private HashMap entities = HashMapFactory.make(); + + /** + * A mapping from type reference for a bean to the BeanMetaData object that + * describes the bean. + */ + private HashMap sessions = HashMapFactory.make(); + + /** + * A mapping from type reference for a bean to the BeanMetaData object that + * describes the bean. + */ + private HashMap MDBs = HashMapFactory.make(); + + /** + * A mapping from type reference for a bean to the BeanMetaData object that + * describes the bean. + */ + private HashMap allBeans = HashMapFactory.make(); + + /** + * A mapping from type reference for a remote interface to the bean that + * implements it. + */ + private HashMap remote2Bean = HashMapFactory.make(); + + /** + * A mapping from type reference for a home interface to the bean that + * implements it. + */ + private HashMap home2Bean = HashMapFactory.make(); + /** + * A mapping from type reference for a local interface to the bean that + * implements it. + */ + private HashMap local2Bean = HashMapFactory.make(); + /** + * A mapping from type reference for a local home interface to the bean that + * implements it. + */ + private HashMap localHome2Bean = HashMapFactory.make(); + + /** + * All container-generated getters and setters; a mapping from MethodReference -> + * FieldReference + */ + private HashMap getters = HashMapFactory.make(); + private HashMap setters = HashMapFactory.make(); + + /** + * All finder methods; a mapping from MethodReference -> Bean + */ + private HashMap finder2Bean = HashMapFactory.make(); + + /** + * All CMR Getters as a mapping from MethodReference to FieldReference + */ + private HashMap cmrGetters = HashMapFactory.make(); + + /** + * All CMR Setters as a mapping from MethodReference to FieldReference + */ + private HashMap cmrSetters = HashMapFactory.make(); + + /** + * For CMR fields, a mapping from FieldReference -> BeanMetaData + */ + private HashMap cmrField2Bean = HashMapFactory.make(); + + /** + * For CMR fields, a mapping from FieldReference -> EJBRelationshipRole + */ + private HashMap cmrField2Role = HashMapFactory.make(); + + /** + * A mapping between opposite fields in CMRs + */ + private HashMap oppositeFields = HashMapFactory.make(); + + /** + * Method DeploymentMetaDataImpl. + * + * @param scope + * the analysis scope which defines the EJB jar files to analyze + */ + @SuppressWarnings({ "restriction", "unchecked" }) + public DeploymentMetaDataImpl(AnalysisScope scope) { + ClassLoaderReference loader = scope.getApplicationLoader(); + + for (Iterator i = scope.getModules(loader).iterator(); i.hasNext();) { + Module module = (Module) i.next(); + // get the file as an EJB Jar archive + Archive archive = J2EEUtil.getArchive(module); + if (archive != null) { + if (archive.isEJBJarFile()) { + processEJBJarFile(loader, (EJBJarFile) archive); + } else if (archive.isEARFile()) { + for (Iterator it = ((EARFile) archive).getEJBJarFiles().iterator(); it.hasNext();) { + EJBJarFile j = (EJBJarFile) it.next(); + processEJBJarFile(loader, j); + } + } + } + } + } + + /** + * @param loader + * governing class loader for the application + * @param archive + * WCCM object which holds the ejb jarfile + */ + @SuppressWarnings({ "restriction", "unchecked" }) + private void processEJBJarFile(ClassLoaderReference loader, EJBJarFile archive) { + // extract the deployment descriptor + EJBJar DD = null; + try { + DD = archive.getDeploymentDescriptor(); + } catch (Throwable e) { + e.printStackTrace(); + Assertions.UNREACHABLE("Failed to load deployment descriptor for " + archive); + } + + // add each bean to the bean map + for (Iterator bi = DD.getEnterpriseBeans().iterator(); bi.hasNext();) { + EnterpriseBean b = (EnterpriseBean) bi.next(); + TypeReference c = J2EEUtil.ejb2TypeReference(b, loader); + + BeanMetaDataImpl bmd = new BeanMetaDataImpl(b, DD, c); + allBeans.put(c, bmd); + if (bmd.isContainerManaged()) { + entities.put(c, bmd); + } else if (bmd.isSessionBean()) { + sessions.put(c, bmd); + } else if (bmd.isMessageDrivenBean()) { + MDBs.put(c, bmd); + } else if (bmd.isBeanManaged()) { + entities.put(c, bmd); + } else { + Assertions.UNREACHABLE("unexpected bean type" + bmd); + } + + String homeName = b.getHomeInterfaceName(); + mapEJBInterface(loader, bmd, homeName, home2Bean); + + String remoteName = b.getRemoteInterfaceName(); + mapEJBInterface(loader, bmd, remoteName, remote2Bean); + + String localName = b.getLocalInterfaceName(); + mapEJBInterface(loader, bmd, localName, local2Bean); + + String localHomeName = b.getLocalHomeInterfaceName(); + mapEJBInterface(loader, bmd, localHomeName, localHome2Bean); + } + + // cache the set of getter and setter methods + computeGettersAndSetters(); + computeFinders(); + computeCMRs(DD, loader); + } + + /** + * Method mapEJBInterface. + * + * @param loader + * the interface's defining class loader + * @param bmd + * data about the bean + * @param iName + * name of the interface + * @param iMap + * mapping from TypeReferece -> BeanMetaData + */ + private void mapEJBInterface(ClassLoaderReference loader, BeanMetaData bmd, String iName, HashMap iMap) { + + if (iName == null) + return; + TypeReference iFace = J2EEUtil.getTypeForInterface(loader, iName); + + // here's a bit of a kludge .. if there's a choice of beans for an + // interface, + // choose the last CMP implementation discovered + BeanMetaData old = iMap.get(iFace); + if (old != null) { + if (old.isContainerManaged()) { + // don't overwrite + return; + } + } + + iMap.put(iFace, bmd); + } + + + public BeanMetaData getBeanMetaData(TypeReference type) { + return allBeans.get(type); + } + + /** + * @see com.ibm.wala.j2ee.DeploymentMetaData#getAllCMPFields() + */ + public Set getAllCMPFields() { + HashSet result = HashSetFactory.make(); + for (Iterator> i = entities.entrySet().iterator(); i.hasNext();) { + Map.Entry entry = (Map.Entry) i.next(); + BeanMetaData bean = (BeanMetaData) entry.getValue(); + result.addAll(bean.getCMPFields()); + } + return result; + } + + /** + * Return a Set of container managed relationship (cmr) fields. + * + * @see com.ibm.wala.j2ee.DeploymentMetaData#getAllCMRFields() + * @return Set of container managed relationship fields. + */ + public Set getAllCMRFields() { + HashSet result = HashSetFactory.make(); + for (Iterator> i = entities.entrySet().iterator(); i.hasNext();) { + Map.Entry entry = (Map.Entry) i.next(); + BeanMetaData bean = (BeanMetaData) entry.getValue(); + result.addAll(bean.getCMRFields()); + } + return result; + } + + private void computeGettersAndSetters() { + for (Iterator> i = entities.entrySet().iterator(); i.hasNext();) { + Map.Entry entry = (Map.Entry) i.next(); + BeanMetaData bean = (BeanMetaData) entry.getValue(); + getters.putAll(bean.getGetterMethods()); + setters.putAll(bean.getSetterMethods()); + } + } + + /** + * Set up the finder2Bean relation, which maps each finder method to its bean + */ + private void computeFinders() { + for (Iterator> i = entities.entrySet().iterator(); i.hasNext();) { + Map.Entry entry = (Map.Entry) i.next(); + BeanMetaData bean = (BeanMetaData) entry.getValue(); + for (Iterator j = bean.getFinders().iterator(); j.hasNext();) { + MethodReference m = j.next(); + if (DEBUG) { + Trace.println("Found finder " + m); + } + finder2Bean.put(m, bean); + } + } + } + + /** + * Set up mappings for CMRs + *
                                + *
                              • set up mapping from MethodReference -> FieldReference for CMR getters + *
                              • set up mapping from FieldReference -> BeanMetaData for CMR Fields + *
                              + */ + @SuppressWarnings("unchecked") + private void computeCMRs(EJBJar DD, ClassLoaderReference loader) { + for (Iterator i = entities.values().iterator(); i.hasNext();) { + BeanMetaData bean = i.next(); + cmrGetters.putAll(bean.getCMRGetters()); + cmrSetters.putAll(bean.getCMRSetters()); + } + if (DD.getEjbRelations() != null) { + for (Iterator it = DD.getEjbRelations().iterator(); it.hasNext();) { + EJBRelation relation = (EJBRelation) it.next(); + EJBRelationshipRole firstRole = relation.getFirstRole(); + EJBRelationshipRole secondRole = relation.getSecondRole(); + CMRField firstField = firstRole.getCmrField(); + FieldReference f1 = null; + FieldReference f2 = null; + if (firstField != null) { + EnterpriseBean sourceBean = firstRole.getSourceEntity(); + TypeReference b = J2EEUtil.ejb2TypeReference(sourceBean, loader); + BeanMetaData sourceBeanData = entities.get(b); + f1 = sourceBeanData.getField(firstField); + EnterpriseBean otherBean = secondRole.getSourceEntity(); + TypeReference o = J2EEUtil.ejb2TypeReference(otherBean, loader); + cmrField2Bean.put(f1, entities.get(o)); + cmrField2Role.put(f1, firstRole); + } + CMRField secondField = secondRole.getCmrField(); + if (secondField != null) { + EnterpriseBean sourceBean = secondRole.getSourceEntity(); + TypeReference b = J2EEUtil.ejb2TypeReference(sourceBean, loader); + BeanMetaData sourceBeanData = entities.get(b); + f2 = sourceBeanData.getField(secondField); + EnterpriseBean otherBean = firstRole.getSourceEntity(); + TypeReference o = J2EEUtil.ejb2TypeReference(otherBean, loader); + cmrField2Bean.put(f2, entities.get(o)); + cmrField2Role.put(f2, secondRole); + } + if (firstField != null && secondField != null) { + oppositeFields.put(f1, f2); + oppositeFields.put(f2, f1); + } + } + } + } + + /** + * @see com.ibm.wala.j2ee.DeploymentMetaData#isHomeInterface(TypeReference) + */ + public boolean isHomeInterface(TypeReference t) { + return home2Bean.keySet().contains(t); + } + + /** + * @see com.ibm.wala.j2ee.DeploymentMetaData#isRemoteInterface(TypeReference) + */ + public boolean isRemoteInterface(TypeReference t) { + return remote2Bean.keySet().contains(t); + } + + /** + * @see com.ibm.wala.j2ee.DeploymentMetaData#isHomeInterface(TypeReference) + */ + public boolean isLocalInterface(TypeReference t) { + return local2Bean.keySet().contains(t); + } + + /** + * @see com.ibm.wala.j2ee.DeploymentMetaData#isRemoteInterface(TypeReference) + */ + public boolean isLocalHomeInterface(TypeReference t) { + return localHome2Bean.keySet().contains(t); + } + + public boolean isEJBInterface(TypeReference t) { + return isHomeInterface(t) || isRemoteInterface(t) || isLocalInterface(t) || isLocalHomeInterface(t); + } + + /** + * @see com.ibm.wala.j2ee.DeploymentMetaData#getBeanForInterface(TypeReference) + */ + public BeanMetaData getBeanForInterface(TypeReference t) { + BeanMetaData bmd = remote2Bean.get(t); + if (bmd == null) { + bmd = home2Bean.get(t); + } + if (bmd == null) { + bmd = local2Bean.get(t); + } + if (bmd == null) { + bmd = localHome2Bean.get(t); + } + + return bmd; + } + + public TypeReference getCMPType(TypeReference t) { + BeanMetaData bmd = entities.get(t); + return (bmd == null) ? null : bmd.getEJBClass(); + } + + /** + * @see com.ibm.wala.j2ee.DeploymentMetaData#isContainerManaged(TypeReference) + */ + public boolean isContainerManaged(TypeReference t) { + BeanMetaData bmd = allBeans.get(t); + if (bmd == null) { + return false; + } + return bmd.isContainerManaged(); + } + + /** + * @see com.ibm.wala.j2ee.DeploymentMetaData#getCMPField(MethodReference) + */ + public FieldReference getCMPField(MethodReference mr) { + if (getters.get(mr) != null) { + return getters.get(mr); + } else { + return setters.get(mr); + } + } + + /** + * @see com.ibm.wala.j2ee.DeploymentMetaData#isCMPGetter(MethodReference) + */ + public boolean isCMPGetter(MethodReference mr) { + return getters.keySet().contains(mr); + } + + /** + * @see com.ibm.wala.j2ee.DeploymentMetaData#isCMPSetter(MethodReference) + */ + public boolean isCMPSetter(MethodReference mr) { + return setters.keySet().contains(mr); + } + + /** + * @see com.ibm.wala.j2ee.DeploymentMetaData#getAllFinders() + */ + public Collection getAllFinders() { + return finder2Bean.keySet(); + } + + /** + * @see com.ibm.wala.j2ee.DeploymentMetaData#getAllCMRGetters() + */ + public Map getAllCMRGetters() { + return cmrGetters; + } + + /** + * @see com.ibm.wala.j2ee.DeploymentMetaData#getCMRBean(FieldReference) + */ + public BeanMetaData getCMRBean(FieldReference field) { + return cmrField2Bean.get(field); + } + + /* + * (non-Javadoc) + * + * @see com.ibm.wala.j2ee.DeploymentMetaData#getFinderBeanType(com.ibm.wala.classLoader.MethodReference) + */ + public TypeReference getFinderBeanType(MethodReference method) { + BeanMetaData bean = finder2Bean.get(method); + if (Assertions.verifyAssertions) { + Assertions._assert(bean != null); + } + return bean.getEJBClass(); + } + + /* + * (non-Javadoc) + * + * @see com.ibm.wala.j2ee.DeploymentMetaData#isFinder(com.ibm.wala.classLoader.MethodReference) + */ + public boolean isFinder(MethodReference ref) { + if (DEBUG) { + boolean result = finder2Bean.keySet().contains(ref); + Trace.println("isFinder ? " + ref + " " + result); + } + return finder2Bean.keySet().contains(ref); + } + + /* + * (non-Javadoc) + * + * @see com.ibm.wala.j2ee.DeploymentMetaData#iterateEntities() + */ + public Iterator iterateEntities() { + return entities.values().iterator(); + } + + /* + * (non-Javadoc) + * + * @see com.ibm.wala.j2ee.DeploymentMetaData#iterateSessions() + */ + public Iterator iterateSessions() { + return sessions.values().iterator(); + } + + /* + * (non-Javadoc) + * + * @see com.ibm.wala.j2ee.DeploymentMetaData#iterateSessions() + */ + public Iterator iterateMDBs() { + return MDBs.values().iterator(); + } + + /* + * (non-Javadoc) + * + * @see com.ibm.wala.j2ee.DeploymentMetaData#isCMRGetter(com.ibm.wala.classLoader.MethodReference) + */ + public boolean isCMRGetter(MethodReference method) { + return cmrGetters.keySet().contains(method); + } + + /* + * (non-Javadoc) + * + * @see com.ibm.wala.j2ee.DeploymentMetaData#isCMRGetter(com.ibm.wala.classLoader.MethodReference) + */ + public boolean isCMRSetter(MethodReference method) { + return cmrSetters.keySet().contains(method); + } + + /* + * (non-Javadoc) + * + * @see com.ibm.wala.j2ee.DeploymentMetaData#getOppositeField(com.ibm.wala.classLoader.FieldReference) + */ + public FieldReference getOppositeField(FieldReference field) { + return oppositeFields.get(field); + } + + /* + * (non-Javadoc) + * + * @see com.ibm.wala.j2ee.DeploymentMetaData#getCMRRole(com.ibm.wala.classLoader.FieldReference) + */ + public EJBRelationshipRole getCMRRole(FieldReference field) { + return cmrField2Role.get(field); + } + + /* (non-Javadoc) + * @see com.ibm.wala.j2ee.DeploymentMetaData#isMessageDriven(com.ibm.wala.classLoader.TypeReference) + */ + public boolean isMessageDriven(TypeReference type) { + return MDBs.containsKey(type); + } +} \ No newline at end of file diff --git a/com.ibm.wala.j2ee/src/com/ibm/wala/j2ee/EJBConstants.java b/com.ibm.wala.j2ee/src/com/ibm/wala/j2ee/EJBConstants.java new file mode 100644 index 000000000..81f344aa5 --- /dev/null +++ b/com.ibm.wala.j2ee/src/com/ibm/wala/j2ee/EJBConstants.java @@ -0,0 +1,105 @@ +/******************************************************************************* + * 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.j2ee; + +import com.ibm.wala.types.ClassLoaderReference; +import com.ibm.wala.types.Descriptor; +import com.ibm.wala.types.TypeReference; +import com.ibm.wala.util.Atom; +import com.ibm.wala.util.ImmutableByteArray; +import com.ibm.wala.util.UTF8Convert; + +/** + * + * Constants defined in the EJB SPEC. + * + * @author sfink + */ +public interface EJBConstants { + /* + * Some method names defined in the EJB spec + */ + + public final static Atom ejbRemoveAtom = Atom.findOrCreateAsciiAtom("ejbRemove"); + public final static byte[] ejbRemoveSig = UTF8Convert.toUTF8("()V"); + + public final static Atom ejbActivateAtom = Atom.findOrCreateAsciiAtom("ejbActivate"); + public final static byte[] ejbActivateSig = UTF8Convert.toUTF8("()V"); + + public final static Atom ejbPassivateAtom = Atom.findOrCreateAsciiAtom("ejbPassivate"); + public final static byte[] ejbPassivateSig = UTF8Convert.toUTF8("()V"); + + public final static Atom ejbLoadAtom = Atom.findOrCreateAsciiAtom("ejbLoad"); + public final static byte[] ejbLoadSig = UTF8Convert.toUTF8("()V"); + + public final static Atom ejbStoreAtom = Atom.findOrCreateAsciiAtom("ejbStore"); + public final static byte[] ejbStoreSig = UTF8Convert.toUTF8("()V"); + + public final static Atom setSessionContextAtom = Atom.findOrCreateAsciiAtom("setSessionContext"); + public final static byte[] setSessionContextSig = UTF8Convert.toUTF8("(Ljavax/ejb/SessionContext;)V"); + public final static Descriptor setSessionContextDescriptor = + Descriptor.findOrCreate(new ImmutableByteArray(setSessionContextSig)); + + public final static Atom setEntityContextAtom = Atom.findOrCreateAsciiAtom("setEntityContext"); + public final static byte[] setEntityContextSig = UTF8Convert.toUTF8("(Ljavax/ejb/EntityContext;)V"); + + public final static Atom unsetEntityContextAtom = Atom.findOrCreateAsciiAtom("unsetEntityContext"); + public final static byte[] unsetEntityContextSig = UTF8Convert.toUTF8("()V"); + + public final static Atom onMessageAtom = Atom.findOrCreateAsciiAtom("onMessage"); + public final static byte[] onMessageBytes = UTF8Convert.toUTF8("(Ljavax/jms/Message;)V"); + public final Descriptor onMessageDesc = Descriptor.findOrCreate(new ImmutableByteArray(onMessageBytes)); + + // some special methods defined by the contract for entity bean interfaces + public static final Atom CREATE = Atom.findOrCreateAsciiAtom("create"); + public static final Atom EJB_CREATE = Atom.findOrCreateAsciiAtom("ejbCreate"); + public static final Atom EJB_POST_CREATE = Atom.findOrCreateAsciiAtom("ejbPostCreate"); + public static final Atom REMOVE = Atom.findOrCreateAsciiAtom("remove"); + public static final Atom EJB_REMOVE = Atom.findOrCreateAsciiAtom("ejbRemove"); + public static final Atom GET_PRIMARY_KEY = Atom.findOrCreateAsciiAtom("getPrimaryKey"); + public static final Atom GET_EJB_META_DATA = Atom.findOrCreateAsciiAtom("getEJBMetaData"); + public static final Atom GET_EJB_HOME = Atom.findOrCreateAsciiAtom("getEJBHome"); + public static final Atom GET_HANDLE = Atom.findOrCreateAsciiAtom("getHandle"); + public static final Atom IS_IDENTICAL = Atom.findOrCreateAsciiAtom("isIdentical"); + + // special-case support for some exceptions + public final static TypeReference CreateExceptionClass = + TypeReference.findOrCreateClass(ClassLoaderReference.Extension, "javax/ejb", "CreateException"); + + public final static TypeReference EJBExceptionClass = + TypeReference.findOrCreateClass(ClassLoaderReference.Extension, "javax/ejb", "EJBException"); + + public final static TypeReference FinderExceptionClass = + TypeReference.findOrCreateClass(ClassLoaderReference.Extension, "javax/ejb", "FinderException"); + + public final static TypeReference RemoveExceptionClass = + TypeReference.findOrCreateClass(ClassLoaderReference.Extension, "javax/ejb", "RemoveException"); + + public final static TypeReference RemoteExceptionClass = + TypeReference.findOrCreateClass(ClassLoaderReference.Extension, "java/rmi", "RemoteException"); + + public final static TypeReference ObjectNotFoundExceptionClass = + TypeReference.findOrCreateClass(ClassLoaderReference.Extension, "javax/ejb", "ObjectNotFoundException"); + + public final static TypeReference MessageClass = + TypeReference.findOrCreateClass(ClassLoaderReference.Extension, "javax/jms", "Message"); + public final static TypeReference BytesMessageClass = + TypeReference.findOrCreateClass(ClassLoaderReference.Extension, "javax/jms", "BytesMessage"); + public final static TypeReference ObjectMessageClass = + TypeReference.findOrCreateClass(ClassLoaderReference.Extension, "javax/jms", "ObjectMessage"); + public final static TypeReference StreamMessageClass = + TypeReference.findOrCreateClass(ClassLoaderReference.Extension, "javax/jms", "StreamMessage"); + public final static TypeReference TextMessageClass = + TypeReference.findOrCreateClass(ClassLoaderReference.Extension, "javax/jms", "TextMessage"); + public final static TypeReference[] KnownMessages = + new TypeReference[] { MessageClass, BytesMessageClass, ObjectMessageClass, StreamMessageClass, TextMessageClass }; +} diff --git a/com.ibm.wala.j2ee/src/com/ibm/wala/j2ee/EJBEntrypoints.java b/com.ibm.wala.j2ee/src/com/ibm/wala/j2ee/EJBEntrypoints.java new file mode 100644 index 000000000..518a44fe4 --- /dev/null +++ b/com.ibm.wala.j2ee/src/com/ibm/wala/j2ee/EJBEntrypoints.java @@ -0,0 +1,351 @@ +/******************************************************************************* + * 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.j2ee; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.eclipse.jem.java.Method; +import org.eclipse.jst.j2ee.commonarchivecore.internal.Archive; +import org.eclipse.jst.j2ee.commonarchivecore.internal.EARFile; +import org.eclipse.jst.j2ee.commonarchivecore.internal.EJBJarFile; +import org.eclipse.jst.j2ee.ejb.EJBJar; +import org.eclipse.jst.j2ee.ejb.EnterpriseBean; +import org.eclipse.jst.j2ee.ejb.MessageDriven; + +import com.ibm.wala.classLoader.IClass; +import com.ibm.wala.classLoader.IMethod; +import com.ibm.wala.classLoader.Module; +import com.ibm.wala.classLoader.NewSiteReference; +import com.ibm.wala.ipa.callgraph.Entrypoint; +import com.ibm.wala.ipa.callgraph.Entrypoints; +import com.ibm.wala.ipa.callgraph.impl.DefaultEntrypoint; +import com.ibm.wala.ipa.cha.ClassHierarchy; +import com.ibm.wala.types.ClassLoaderReference; +import com.ibm.wala.types.Descriptor; +import com.ibm.wala.types.MethodReference; +import com.ibm.wala.types.TypeReference; +import com.ibm.wala.util.Atom; +import com.ibm.wala.util.ImmutableByteArray; +import com.ibm.wala.util.collections.HashMapFactory; +import com.ibm.wala.util.collections.HashSetFactory; +import com.ibm.wala.util.debug.Assertions; +import com.ibm.wala.util.debug.Trace; +import com.ibm.wala.util.warnings.WarningSet; + +/** + * + * This class provides an enumeration of EJB methods as listed in EJB jar file + * deployment descriptors + * + * @author sfink + */ +public class EJBEntrypoints implements Entrypoints, EJBConstants { + static final boolean DEBUG = false; + + private final ClassHierarchy cha; + + /** + * The set of Entrypoint for call graph construction. + */ + private List entrypoints = new LinkedList(); + + /** + * Should we include only MDB entrypoints + */ + private final boolean JUST_MDBS; + + /** + * Method names in the Entity Bean interface + */ + private final static Map entityBeanMethodNames = makeEntityBeanMethodMap(); + + private final static Map makeEntityBeanMethodMap() { + HashMap result = HashMapFactory.make(10); + result.put(ejbActivateAtom, new ImmutableByteArray(ejbActivateSig)); + result.put(ejbLoadAtom, new ImmutableByteArray(ejbLoadSig)); + result.put(ejbPassivateAtom, new ImmutableByteArray(ejbPassivateSig)); + result.put(ejbRemoveAtom, new ImmutableByteArray(ejbRemoveSig)); + result.put(ejbStoreAtom, new ImmutableByteArray(ejbStoreSig)); + result.put(setEntityContextAtom, new ImmutableByteArray(setEntityContextSig)); + result.put(unsetEntityContextAtom, new ImmutableByteArray(unsetEntityContextSig)); + return result; + } + + /** + * Method names in the Session Bean interface + */ + private final static Map sessionBeanMethodNames = makeSessionBeanMethodMap(); + + private final static Map makeSessionBeanMethodMap() { + HashMap result = HashMapFactory.make(5); + result.put(ejbActivateAtom, new ImmutableByteArray(ejbActivateSig)); + result.put(ejbPassivateAtom, new ImmutableByteArray(ejbPassivateSig)); + result.put(ejbRemoveAtom, new ImmutableByteArray(ejbRemoveSig)); + result.put(setSessionContextAtom, new ImmutableByteArray(setSessionContextSig)); + return result; + } + + /** + * Governing deployment descriptor information + */ + private DeploymentMetaData deployment; + + private final J2EEClassTargetSelector classTargetSelector; + + private final WarningSet warnings; + + /** + * Create the set of EJB entrypoints that are defined in an analysis scope + * + * @param scope + * representation of the analysis scope. + */ + @SuppressWarnings({ "restriction", "unchecked" }) + public EJBEntrypoints(ClassHierarchy cha, J2EEAnalysisScope scope, DeploymentMetaData deployment, boolean justMDBs, + J2EEClassTargetSelector classTargetSelector, WarningSet warnings) { + this.cha = cha; + this.deployment = deployment; + this.JUST_MDBS = justMDBs; + this.warnings = warnings; + this.classTargetSelector = classTargetSelector; + ClassLoaderReference loader = scope.getApplicationLoader(); + + addEntrypointForSyntheticContainer(); + for (Iterator i = scope.getModules(loader).iterator(); i.hasNext();) { + Module M = (Module) i.next(); + // get the file as an EJB Jar archive + Archive archive = J2EEUtil.getArchive(M); + if (archive.isEJBJarFile()) { + addEntrypointsForEJBJarFile(scope, loader, archive); + } else if (archive.isEARFile()) { + EARFile ear = (EARFile) archive; + for (Iterator it = ear.getEJBJarFiles().iterator(); it.hasNext();) { + EJBJarFile j = (EJBJarFile) it.next(); + addEntrypointsForEJBJarFile(scope, loader, j); + } + } + } + } + + /** + * Add an entrypoint which initializes the J2EE Container model + */ + private void addEntrypointForSyntheticContainer() { + final J2EEContainerModel klass = new J2EEContainerModel(deployment, cha); + entrypoints.add(new DefaultEntrypoint(klass.getClassInitializer().getReference(), cha) { + public TypeReference[] getParameterTypes(int i) { + if (i == 0) { + return new TypeReference[] { classTargetSelector.getAllocatedTarget(null, NewSiteReference.make(0, klass.getReference())) + .getReference() }; + } else { + Assertions.UNREACHABLE(); + return null; + } + } + }); + } + + /** + * @param scope + * analysis scope + * @param loader + * application class loader + * @param archive + * WCCM representation of EJB jar file. + */ + @SuppressWarnings({ "restriction", "unchecked" }) + private void addEntrypointsForEJBJarFile(J2EEAnalysisScope scope, ClassLoaderReference loader, Archive archive) { + // extract the deployment descriptor + EJBJar DD = ((EJBJarFile) archive).getDeploymentDescriptor(); + + // iterate over each bean described + for (Iterator bi = DD.getEnterpriseBeans().iterator(); bi.hasNext();) { + EnterpriseBean b = (EnterpriseBean) bi.next(); + + if (b.hasRemoteClient() && !JUST_MDBS) { + // add each method in the remote interface as an entrypoint + addRemoteMethods(b, b.getRemoteMethodsForDeployment(), loader); + // add each method in the home interface as an entrypoint + addHomeMethods(b, b.getHomeMethodsForDeployment(), loader); + + if (scope.useEJBLifecycleEntrypoints()) { + addEJBLifecycleEntrypoints(b, loader); + } + } else if (b.isMessageDriven()) { + addMessageDestination((MessageDriven) b, loader); + } + } + + // prune the set of entrypoints based on transaction declarations + pruneEntrypointsByTransactions(archive, loader); + } + + /** + * @param b + * @param loader + */ + private void addMessageDestination(MessageDriven b, ClassLoaderReference loader) { + + TypeReference T = J2EEUtil.ejb2TypeReference(b, loader); + MethodReference e = MethodReference.findOrCreate(T, onMessageAtom, onMessageDesc); + if (DEBUG) { + Trace.println("Add entrypoint: " + e + " from bean " + b); + } + IMethod m = cha.resolveMethod(e); + if (m == null) { + warnings.add(LoadFailure.create(e)); + return; + } + entrypoints.add(new MDBEntrypoint(m, cha, T)); + } + + /** + * Remove any entrypoints that are marked as MANDATORY transactions; we can't + * call these from the outside world without raising an exception. + * + * TODO: this algorithm is inefficient; but it shouldn't matter, since this is + * a one-time cost on a small set, I hope. If this is a problem, represent the + * entrypoints as a Map from MethodReference -> Entrypoint, to allow constant + * time deletions. + */ + private void pruneEntrypointsByTransactions(Archive A, ClassLoaderReference loader) { + Set S = TransactionUtil.createDeclaredTransactionEntries(A, loader); + Set M = HashSetFactory.make(); // set of MethodReferences to prune. + for (Iterator it = S.iterator(); it.hasNext();) { + DeploymentDeclaredTransaction X = (DeploymentDeclaredTransaction) it.next(); + if (X.isMandatory()) { + M.add(X.getMethodReference()); + } + } + // walk through the list of entrypoints and delete any in set M. + Set toRemove = HashSetFactory.make(); + for (Iterator it = entrypoints.iterator(); it.hasNext();) { + Entrypoint E = it.next(); + MethodReference m = E.getMethod().getReference(); + if (M.contains(m)) { + toRemove.add(E); + } + } + entrypoints.removeAll(toRemove); + } + + /** + * @param b + * @param methods + * @param loader + */ + private void addRemoteMethods(EnterpriseBean b, Method[] methods, ClassLoaderReference loader) { + TypeReference T = J2EEUtil.ejb2TypeReference(b, loader); + BeanMetaData bean = deployment.getBeanMetaData(T); + + TypeReference remoteInterface = bean.getRemoteInterface(); + addMethods(bean, remoteInterface, methods, loader); + } + + /** + * @param b + * @param methods + * @param loader + */ + private void addHomeMethods(EnterpriseBean b, Method[] methods, ClassLoaderReference loader) { + TypeReference T = J2EEUtil.ejb2TypeReference(b, loader); + BeanMetaData bean = deployment.getBeanMetaData(T); + TypeReference remoteInterface = bean.getHomeInterface(); + addMethods(bean, remoteInterface, methods, loader); + } + + /** + * @param b + */ + private void addEJBLifecycleEntrypoints(EnterpriseBean b, ClassLoaderReference loader) { + TypeReference type = J2EEUtil.ejb2TypeReference(b, loader); + + Iterator> i = b.isSession() ? sessionBeanMethodNames.entrySet().iterator() : entityBeanMethodNames.entrySet().iterator(); + while (i.hasNext()) { + Map.Entry entry = i.next(); + Atom name = (Atom) entry.getKey(); + ImmutableByteArray sig = (ImmutableByteArray) entry.getValue(); + Descriptor D = Descriptor.findOrCreate(sig); + MethodReference e = MethodReference.findOrCreate(type, name, D); + if (DEBUG) { + Trace.println("Add entrypoint: " + e + " from bean " + b); + } + IMethod m = cha.resolveMethod(e); + if (m == null) { + warnings.add(LoadFailure.create(m)); + continue; + } + entrypoints.add(new EJBLifecycleEntrypoint(m, cha, type)); + } + + } + + /** + * Add some EJB methods to the entrypoint set + * + * @param bean + * @param interfaceType + * @param methods + * array of Method from the bean + * @param loader + */ + private void addMethods(final BeanMetaData bean, TypeReference interfaceType, Method[] methods, ClassLoaderReference loader) { + for (int i = 0; i < methods.length; i++) { + Method method = methods[i]; + MethodReference declaredMethod = J2EEUtil.createMethodReference(method, loader); + MethodReference target = MethodReference + .findOrCreate(interfaceType, declaredMethod.getName(), declaredMethod.getDescriptor()); + if (DEBUG) { + Trace.println("Add entrypoint: " + target + " from method list"); + } + final IClass klass = cha.lookupClass(interfaceType); + if (klass == null) { + warnings.add(LoadFailure.create(interfaceType)); + continue; + } + IMethod m = cha.resolveMethod(klass, target.getSelector()); + if (m == null) { + warnings.add(LoadFailure.create(target)); + continue; + } + entrypoints.add(new DefaultEntrypoint(m, cha) { + public TypeReference[] getParameterTypes(int i) { + if (i == 0) { + return new TypeReference[] { classTargetSelector.getAllocatedTarget(null, + NewSiteReference.make(0, klass.getReference())).getReference() }; + } else { + return super.getParameterTypes(i); + } + } + }); + } + } + + public Iterator iterator() { + return entrypoints.iterator(); + } + + /** + * @see java.lang.Object#toString() + */ + public String toString() { + String result = ""; + for (Iterator i = entrypoints.iterator(); i.hasNext();) { + result += i.next() + "\n"; + } + return result; + } +} \ No newline at end of file diff --git a/com.ibm.wala.j2ee/src/com/ibm/wala/j2ee/EJBLifecycleEntrypoint.java b/com.ibm.wala.j2ee/src/com/ibm/wala/j2ee/EJBLifecycleEntrypoint.java new file mode 100644 index 000000000..4c07248f4 --- /dev/null +++ b/com.ibm.wala.j2ee/src/com/ibm/wala/j2ee/EJBLifecycleEntrypoint.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * 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.j2ee; + +import com.ibm.wala.classLoader.IMethod; +import com.ibm.wala.ipa.callgraph.impl.DefaultEntrypoint; +import com.ibm.wala.ipa.cha.ClassHierarchy; +import com.ibm.wala.types.TypeReference; + +class EJBLifecycleEntrypoint extends DefaultEntrypoint { + + private final TypeReference bean; + + EJBLifecycleEntrypoint(IMethod m, ClassHierarchy cha, TypeReference bean) { + super(m, cha); + this.bean = bean; + } + + public TypeReference[] getParameterTypes(int i) { + if (i == 0) { + // special logic for "this" + return new TypeReference[] {bean}; + } else { + return super.getParameterTypes(i); + } + } + +} diff --git a/com.ibm.wala.j2ee/src/com/ibm/wala/j2ee/IDeclaredTransaction.java b/com.ibm.wala.j2ee/src/com/ibm/wala/j2ee/IDeclaredTransaction.java new file mode 100644 index 000000000..9a012156d --- /dev/null +++ b/com.ibm.wala.j2ee/src/com/ibm/wala/j2ee/IDeclaredTransaction.java @@ -0,0 +1,30 @@ +package com.ibm.wala.j2ee; + +import org.eclipse.jst.j2ee.ejb.EnterpriseBean; +import org.eclipse.jst.j2ee.ejb.MethodElement; + +import com.ibm.wala.types.MethodReference; + +/** + * @author sfink + */ +public interface IDeclaredTransaction extends Comparable { + + public abstract MethodReference getMethodReference(); + + public abstract boolean isRequired(); + + public abstract boolean isRequiresNew(); + + public abstract boolean isNotSupported(); + + public abstract boolean isNever(); + + public abstract boolean isMandatory(); + + public abstract boolean isSupports(); + + public abstract EnterpriseBean getBean(); + + public abstract MethodElement getMethodElement(); +} \ No newline at end of file diff --git a/com.ibm.wala.j2ee/src/com/ibm/wala/j2ee/J2EEAnalysisScope.java b/com.ibm.wala.j2ee/src/com/ibm/wala/j2ee/J2EEAnalysisScope.java new file mode 100644 index 000000000..0b3655889 --- /dev/null +++ b/com.ibm.wala.j2ee/src/com/ibm/wala/j2ee/J2EEAnalysisScope.java @@ -0,0 +1,145 @@ +/******************************************************************************* + * 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.j2ee; + +import java.util.Iterator; +import java.util.jar.JarFile; + +import org.eclipse.emf.ecore.resource.Resource; +import org.eclipse.emf.ecore.xmi.impl.XMIResourceFactoryImpl; + +import com.ibm.wala.classLoader.JarFileModule; +import com.ibm.wala.classLoader.Module; +import com.ibm.wala.ecore.j2ee.scope.impl.J2EEScopePackageImpl; +import com.ibm.wala.emf.wrappers.EMFScopeWrapper; +import com.ibm.wala.ipa.callgraph.AnalysisScope; +import com.ibm.wala.types.ClassLoaderReference; + +/** + * + * Description of analysis for EJBs + * + * @author sfink + */ +@SuppressWarnings("unchecked") +public class J2EEAnalysisScope extends EMFScopeWrapper { + + private final static String BASIC_FILE = "SyntheticContainerModel.xml"; + + private final static String DEFAULT_FILE = "DefaultWebsphereModules.xml"; + + private final static String EXCLUSIONS_FILE = "J2EEClassHierarchyExclusions.xml"; + + private final boolean lifecycleEntrypoints; + + static { + J2EEScopePackageImpl.init(); + Resource.Factory.Registry.INSTANCE.getExtensionToFactoryMap().put("*", new XMIResourceFactoryImpl()); + } + + /** + * @param lifecycleEntrypoints + * Should EJB lifecycle entrypoints be considered as call graph + * entrypoints? + */ + public J2EEAnalysisScope(String baseScope, ClassLoader loader, boolean lifecycleEntrypoints) { + this(baseScope, loader, EXCLUSIONS_FILE, lifecycleEntrypoints); + } + + /** + * @param lifecycleEntrypoints + * Should EJB lifecycle entrypoints be considered as call graph + * entrypoints? + */ + public J2EEAnalysisScope(String baseScope, ClassLoader loader, String exclusionsFile, boolean lifecycleEntrypoints) { + super(baseScope, exclusionsFile, loader); + this.lifecycleEntrypoints = lifecycleEntrypoints; + } + + + /** + * @param lifecycleEntrypoints + * Should EJB lifecycle entrypoints be considered as call graph + * entrypoints? + */ + public static J2EEAnalysisScope makeDefault(ClassLoader loader, boolean lifecycleEntrypoints) { + return new J2EEAnalysisScope(DEFAULT_FILE, loader, lifecycleEntrypoints); + } + + public static J2EEAnalysisScope make(JarFile[] J2SELibs, JarFile[] J2EELibs, ClassLoader loader, boolean lifecycleEntrypoints) { + return make(J2SELibs, J2EELibs, EXCLUSIONS_FILE, loader, lifecycleEntrypoints); + } + + + + /** + * @param lifecycleEntrypoints + * Should EJB lifecycle entrypoints be considered as call graph + * entrypoints? + */ + public static J2EEAnalysisScope make(JarFile[] J2SELibs, JarFile[] J2EELibs, String exclusionsFile, ClassLoader loader, + boolean lifecycleEntrypoints) { + J2EEAnalysisScope scope; + scope = new J2EEAnalysisScope(BASIC_FILE, loader, exclusionsFile, lifecycleEntrypoints); + for (int i = 0; i < J2SELibs.length; i++) { + JarFileModule lib = new JarFileModule(J2SELibs[i]); + scope.addToScope(scope.getPrimordialLoader(), lib); + } + for (int i = 0; i < J2EELibs.length; i++) { + JarFileModule lib = new JarFileModule(J2EELibs[i]); + scope.addToScope(scope.getExtensionLoader(), lib); + } + + return scope; + } + + /** + * @param lifecycleEntrypoints + * Should EJB lifecycle entrypoints be considered as call graph + * entrypoints? + */ + public static J2EEAnalysisScope make(Module[] J2SELibs, Module[] J2EELibs, String exclusionsFile, ClassLoader loader, + boolean lifecycleEntrypoints) { + J2EEAnalysisScope scope; + if (exclusionsFile == null) { + exclusionsFile = EXCLUSIONS_FILE; + } + scope = new J2EEAnalysisScope(BASIC_FILE, loader, exclusionsFile, lifecycleEntrypoints); + for (int i = 0; i < J2SELibs.length; i++) { + scope.addToScope(scope.getPrimordialLoader(), J2SELibs[i]); + } + for (int i = 0; i < J2EELibs.length; i++) { + scope.addToScope(scope.getExtensionLoader(), J2EELibs[i]); + } + + return scope; + } + + public boolean useEJBLifecycleEntrypoints() { + return lifecycleEntrypoints; + } + + /** + * Add each Module in application loader of the passed-in scope, to the + * application loader of this scope. + * + * + * @param scope + * an analysis scope. + */ + public void addToApplicationLoader(AnalysisScope scope) { + ClassLoaderReference app = scope.getApplicationLoader(); + for (Iterator it = scope.getModules(app).iterator(); it.hasNext();) { + Module M = (Module) it.next(); + addToScope(getApplicationLoader(), M); + } + } +} diff --git a/com.ibm.wala.j2ee/src/com/ibm/wala/j2ee/J2EEClassTargetSelector.java b/com.ibm.wala.j2ee/src/com/ibm/wala/j2ee/J2EEClassTargetSelector.java new file mode 100644 index 000000000..98d91e714 --- /dev/null +++ b/com.ibm.wala.j2ee/src/com/ibm/wala/j2ee/J2EEClassTargetSelector.java @@ -0,0 +1,129 @@ +/******************************************************************************* + * 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.j2ee; + +import com.ibm.wala.classLoader.IClass; +import com.ibm.wala.classLoader.IClassLoader; +import com.ibm.wala.classLoader.NewSiteReference; +import com.ibm.wala.ipa.callgraph.CGNode; +import com.ibm.wala.ipa.callgraph.ClassTargetSelector; +import com.ibm.wala.ipa.cha.ClassHierarchy; +import com.ibm.wala.ipa.summaries.BypassSyntheticClass; +import com.ibm.wala.ipa.summaries.BypassSyntheticClassLoader; +import com.ibm.wala.types.TypeName; +import com.ibm.wala.types.TypeReference; +import com.ibm.wala.util.debug.Assertions; +import com.ibm.wala.util.debug.Trace; + +/** + * + * A class that selects concrete types for new statements. + * + * @author Julian Dolby (dolby@us.ibm.com) + * @author Stephen Fink + */ +public class J2EEClassTargetSelector implements ClassTargetSelector { + + private static final boolean DEBUG = false; + + /** + * A delegate if the j2ee rules fail + */ + private final ClassTargetSelector parent; + + /** + * Governing deployment information + */ + private final DeploymentMetaData metaData; + + /** + * Governing class hierarchy + */ + private final ClassHierarchy cha; + + private final BypassSyntheticClassLoader bypassLoader; + + /** + * @param parent + * a target selector to delegate to if logic here fails + * @param metaData + * information about the deployment descriptor + * @param cha + * governing class hierarchy + * @param bypassLoader + * class loader to deal with J2EE bypass logic + */ + public J2EEClassTargetSelector(ClassTargetSelector parent, DeploymentMetaData metaData, ClassHierarchy cha, + IClassLoader bypassLoader) { + this.cha = cha; + this.parent = parent; + this.metaData = metaData; + this.bypassLoader = (BypassSyntheticClassLoader) bypassLoader; + + IClass x = new J2EEContainerModel(metaData, cha); + this.bypassLoader.registerClass(J2EEContainerModel.containerModelName, x); + } + + /* + * (non-Javadoc) + * + * @see com.ibm.detox.ipa.callgraph.ClassTargetSelector#getAllocatedTarget(com.ibm.detox.ipa.callgraph.CGNode, + * com.ibm.wala.classLoader.NewSiteReference) + */ + + public IClass getAllocatedTarget(CGNode caller, NewSiteReference site) { + + TypeReference nominalRef = site.getDeclaredType(); + if (DEBUG) { + Trace.println("J2EEClassTargetSelector getAllocatedTarget: " + nominalRef); + } + if (Assertions.verifyAssertions) { + if (nominalRef == null) { + Assertions._assert(nominalRef != null, "null declared type in site " + site); + } + } + IClass realType = cha.lookupClass(nominalRef); + if (realType == null) { + if (DEBUG) { + Trace.println("cha lookup failed. Delegating to " + parent.getClass()); + } + return parent.getAllocatedTarget(caller, site); + } + TypeReference realRef = realType.getReference(); + + if (metaData.isContainerManaged(realRef) || metaData.isEJBInterface(realRef)) { + if (realType.isAbstract() || realType.isInterface()) { + TypeName syntheticName = BypassSyntheticClass.getName(realRef); + IClass result = bypassLoader.lookupClass(syntheticName); + if (result != null) { + return result; + } else { + IClass x = new BypassSyntheticClass(realType, bypassLoader, cha); + bypassLoader.registerClass(syntheticName, x); + return x; + } + } else { + if (Assertions.verifyAssertions) { + if (realType.isInterface()) { + Assertions.UNREACHABLE("did not hijack allocation of " + realType); + } + } + return realType; + } + } else { + if (DEBUG) { + Trace.println("Not bypassed. Delegating to " + parent.getClass()); + } + return parent.getAllocatedTarget(caller, site); + } + } + +} diff --git a/com.ibm.wala.j2ee/src/com/ibm/wala/j2ee/J2EEContainerModel.java b/com.ibm.wala.j2ee/src/com/ibm/wala/j2ee/J2EEContainerModel.java new file mode 100644 index 000000000..dc89179c3 --- /dev/null +++ b/com.ibm.wala.j2ee/src/com/ibm/wala/j2ee/J2EEContainerModel.java @@ -0,0 +1,421 @@ +/******************************************************************************* + * 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.j2ee; + +import java.util.Collection; +import java.util.Collections; +import java.util.Iterator; +import java.util.Map; +import java.util.NoSuchElementException; + +import com.ibm.wala.classLoader.CallSiteReference; +import com.ibm.wala.classLoader.FieldImpl; +import com.ibm.wala.classLoader.IClass; +import com.ibm.wala.classLoader.IClassLoader; +import com.ibm.wala.classLoader.IField; +import com.ibm.wala.classLoader.IMethod; +import com.ibm.wala.classLoader.NewSiteReference; +import com.ibm.wala.classLoader.SyntheticClass; +import com.ibm.wala.ipa.cha.ClassHierarchy; +import com.ibm.wala.ipa.summaries.MethodSummary; +import com.ibm.wala.ipa.summaries.SummarizedMethod; +import com.ibm.wala.shrikeBT.BytecodeConstants; +import com.ibm.wala.shrikeBT.IInvokeInstruction; +import com.ibm.wala.shrikeCT.ClassConstants; +import com.ibm.wala.ssa.SSAInvokeInstruction; +import com.ibm.wala.ssa.SSANewInstruction; +import com.ibm.wala.ssa.SSAPutInstruction; +import com.ibm.wala.types.ClassLoaderReference; +import com.ibm.wala.types.Descriptor; +import com.ibm.wala.types.FieldReference; +import com.ibm.wala.types.MethodReference; +import com.ibm.wala.types.Selector; +import com.ibm.wala.types.TypeName; +import com.ibm.wala.types.TypeReference; +import com.ibm.wala.util.Atom; +import com.ibm.wala.util.collections.HashMapFactory; +import com.ibm.wala.util.collections.Iterator2Collection; +import com.ibm.wala.util.debug.Assertions; + +/** + * + * A synthetic class that models aspects of the J2EE Container. + * + * @author Julian Dolby + * @author Stephen Fink + */ +class J2EEContainerModel extends SyntheticClass implements BytecodeConstants, EJBConstants { + + private final static Atom syntheticLoaderName = Atom.findOrCreateUnicodeAtom("Synthetic"); + + private final static Atom extensionLoaderName = Atom.findOrCreateUnicodeAtom("Extension"); + + private final static ClassLoaderReference syntheticLoaderRef = new ClassLoaderReference(syntheticLoaderName); + + private final static ClassLoaderReference extensionLoaderRef = new ClassLoaderReference(extensionLoaderName); + + public static final TypeName containerModelName = TypeName.string2TypeName("L$ContainerModel"); + + public static final TypeName entityBeanName = TypeName.string2TypeName("Ljavax/ejb/EntityBean"); + + public static final TypeName entityContextName = TypeName.string2TypeName("Ljavax/ejb/EntityContext"); + + public static final TypeName sessionBeanName = TypeName.string2TypeName("Ljavax/ejb/SessionBean"); + + public static final TypeName sessionContextName = TypeName.string2TypeName("Ljavax/ejb/SessionContext"); + + public static final TypeName messageBeanName = TypeName.string2TypeName("Ljavax/ejb/MessageDrivenBean"); + + public static final TypeName messageContextName = TypeName.string2TypeName("Ljavax/ejb/MessageDrivenContext"); + + public static final TypeReference containerModelRef = TypeReference.findOrCreate(syntheticLoaderRef, containerModelName); + + public static final TypeReference entityBeanRef = TypeReference.findOrCreate(extensionLoaderRef, entityBeanName); + + public static final TypeReference entityContextRef = TypeReference.findOrCreate(extensionLoaderRef, entityContextName); + + public static final TypeReference sessionBeanRef = TypeReference.findOrCreate(extensionLoaderRef, sessionBeanName); + + public static final TypeReference sessionContextRef = TypeReference.findOrCreate(extensionLoaderRef, sessionContextName); + + public static final TypeReference messageBeanRef = TypeReference.findOrCreate(extensionLoaderRef, messageBeanName); + + public static final TypeReference messageContextRef = TypeReference.findOrCreate(extensionLoaderRef, messageContextName); + + public static final Descriptor setEntityContextDescriptor = Descriptor.findOrCreate(new TypeName[] { entityContextName }, + TypeReference.VoidName); + + public static final Descriptor setSessionContextDescriptor = Descriptor.findOrCreate(new TypeName[] { sessionContextName }, + TypeReference.VoidName); + + public static final Descriptor setMessageContextDescriptor = Descriptor.findOrCreate(new TypeName[] { messageContextName }, + TypeReference.VoidName); + + public static final MethodReference setEntityContext = MethodReference.findOrCreate(entityBeanRef, Atom + .findOrCreateAsciiAtom("setEntityContext"), setEntityContextDescriptor); + + public static final MethodReference setSessionContext = MethodReference.findOrCreate(sessionBeanRef, Atom + .findOrCreateAsciiAtom("setSessionContext"), setSessionContextDescriptor); + + public static final MethodReference setMessageContext = MethodReference.findOrCreate(messageBeanRef, Atom + .findOrCreateAsciiAtom("setMessageDrivenContext"), setMessageContextDescriptor); + + /** + * Governing deployment information + */ + private final DeploymentMetaData deployment; + + /** + * Governing class hierarchy + */ + private final ClassHierarchy cha; + + J2EEContainerModel(DeploymentMetaData deployment, ClassHierarchy cha) { + super(containerModelRef, cha); + this.cha = cha; + this.deployment = deployment; + initializeStaticFieldRefs(); + } + + public IClassLoader getClassLoader() { + return cha.getLoader(syntheticLoaderRef); + } + + public IClass getSuperclass() { + return cha.lookupClass(TypeReference.JavaLangObject); + } + + public Collection getAllInterfaces() { + return Collections.emptyList(); + } + + public String getSourceFileName() { + return "This synthetic J2EE model class has no source source"; + } + + public Collection getDeclaredInstanceFields() { + return Collections.emptySet(); + } + + public Collection getAllInstanceFields() { + return Collections.emptySet(); + } + + public IMethod getMethod(Selector selector) { + if ((selector.getName() == MethodReference.clinitName) && (selector.getDescriptor().equals(MethodReference.defaultInitDesc))) + return getClassInitializer(); + else + return null; + } + + public Iterator getDeclaredMethods() { + return new Iterator() { + private boolean done = false; + + public void remove() { + throw new UnsupportedOperationException(); + } + + public boolean hasNext() { + return !done; + } + + public IMethod next() { + if (!done) { + done = true; + return getClassInitializer(); + } else + throw new NoSuchElementException(); + } + }; + } + + public String toString() { + return ""; + } + + private Collection staticFieldRefs = null; + + private Map staticFieldMap = null; + + /** + * Create a phony field name which logically holds a pointer to the one true + * instance of a given bean type + */ + public static Atom getBeanFieldName(TypeReference beanType) { + return getBeanFieldName(beanType.getName()); + } + + /** + * Create a phony field name which logically holds a pointer to the one true + * instance of a given bean type TODO: reconsider this atom generator .... + */ + public static Atom getBeanFieldName(TypeName beanTypeName) { + return Atom.findOrCreateUnicodeAtom("$$existing$" + beanTypeName.toString().replace('/', '$')); + } + + /** + * Create a phony field reference which logically holds a pointer to the one + * true instance of a given bean type + */ + public static FieldReference getBeanFieldRef(TypeReference ejbType) { + return FieldReference.findOrCreate(containerModelRef, getBeanFieldName(ejbType), ejbType); + } + + /** + * Create a phony field reference which logically holds a pointer to the one + * true instance of a given bean type + */ + public static FieldReference getBeanFieldRef(BeanMetaData bean) { + return getBeanFieldRef(bean.getEJBClass()); + } + + private void initializeStaticFieldRefs() { + final Iterator entityBeans = deployment.iterateEntities(); + final Iterator sessionBeans = deployment.iterateSessions(); + final Iterator messageBeans = deployment.iterateMDBs(); + Iterator it = new Iterator() { + public void remove() { + throw new UnsupportedOperationException(); + } + + public boolean hasNext() { + return entityBeans.hasNext() || sessionBeans.hasNext() || messageBeans.hasNext(); + } + + public FieldReference next() { + if (entityBeans.hasNext()) { + return getBeanFieldRef(entityBeans.next()); + } else if (sessionBeans.hasNext()) { + return getBeanFieldRef(sessionBeans.next()); + } else { + return getBeanFieldRef(messageBeans.next()); + } + } + }; + staticFieldRefs = new Iterator2Collection(it); + initializeStaticFieldMap(); + } + + private void initializeStaticFieldMap() { + staticFieldMap = HashMapFactory.make(); + for (Iterator fs = staticFieldRefs.iterator(); fs.hasNext();) { + FieldReference f = fs.next(); + staticFieldMap.put(f.getName(), new FieldImpl(this, f, ClassConstants.ACC_STATIC)); + } + } + + /* + * (non-Javadoc) + * + * @see com.ibm.wala.classLoader.IClass#getDeclaredStaticFields() + */ + public Collection getDeclaredStaticFields() { + return staticFieldMap.values(); + } + + public IField getField(Atom name) { + if (staticFieldMap == null) { + initializeStaticFieldMap(); + } + return staticFieldMap.get(name); + } + + private IMethod clinitMethod = null; + + /** + * Create a method for the synthetic container class + * + * @see com.ibm.wala.classLoader.IClass#getClassInitializer() + */ + public IMethod getClassInitializer() { + if (clinitMethod == null) { + MethodReference clinit = MethodReference.findOrCreate(containerModelRef, MethodReference.clinitName, + MethodReference.defaultInitDesc); + MethodSummary code = new MethodSummary(clinit); + code.setStatic(true); + int nextLocal = code.getNumberOfParameters() + 1; + Iterator fields = getDeclaredStaticFields().iterator(); + while (fields.hasNext()) { + FieldReference field = fields.next().getFieldReference(); + TypeReference ejbType = field.getFieldType(); + + // 1. create bean type representing pool objects + int beanAlloc = nextLocal++; + code.addStatement(new SSANewInstruction(beanAlloc, NewSiteReference.make(code.getNextProgramCounter(), ejbType))); + + // 2. call set...Context, as required by lifecycle. + int contextAlloc = nextLocal++; + int ignoredExceptions = nextLocal++; + if (deployment.getBeanMetaData(ejbType).isSessionBean()) { + code.addStatement(new SSANewInstruction(contextAlloc, NewSiteReference.make(code.getNextProgramCounter(), + sessionContextRef))); + code.addStatement(new SSAInvokeInstruction(new int[] { beanAlloc, contextAlloc }, ignoredExceptions, CallSiteReference + .make(code.getNextProgramCounter(), setSessionContext, IInvokeInstruction.Dispatch.INTERFACE))); + } else if (deployment.getBeanMetaData(ejbType).isMessageDrivenBean()) { + code.addStatement(new SSANewInstruction(contextAlloc, NewSiteReference.make(code.getNextProgramCounter(), + messageContextRef))); + code.addStatement(new SSAInvokeInstruction(new int[] { beanAlloc, contextAlloc }, ignoredExceptions, CallSiteReference + .make(code.getNextProgramCounter(), setMessageContext, IInvokeInstruction.Dispatch.INTERFACE))); + // message driven beans also get ejbCreate called at this point + // (or that is how I interpret the spec, such as it is) + int moreIgnoredExceptions = nextLocal++; + MethodReference ejbCreate = MethodReference.findOrCreate(ejbType, EJB_CREATE, Descriptor.findOrCreate(null, + TypeReference.VoidName)); + code.addStatement(new SSAInvokeInstruction(new int[] { beanAlloc }, moreIgnoredExceptions, CallSiteReference.make(code + .getNextProgramCounter(), ejbCreate, IInvokeInstruction.Dispatch.VIRTUAL))); + } else { + code.addStatement(new SSANewInstruction(contextAlloc, NewSiteReference.make(code.getNextProgramCounter(), + entityContextRef))); + code.addStatement(new SSAInvokeInstruction(new int[] { beanAlloc, contextAlloc }, ignoredExceptions, CallSiteReference + .make(code.getNextProgramCounter(), setEntityContext, IInvokeInstruction.Dispatch.INTERFACE))); + } + + // 3. put bean into static field representing pool. + code.addStatement(new SSAPutInstruction(beanAlloc, field)); + } + + clinitMethod = new SummarizedMethod(clinit, code, this); + } + + return clinitMethod; + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#equals(java.lang.Object) + */ + public boolean equals(Object arg0) { + return arg0.getClass().equals(getClass()); + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#hashCode() + */ + public int hashCode() { + return 7; + } + + /* + * (non-Javadoc) + * + * @see com.ibm.wala.classLoader.IClass#getModifiers() + */ + public int getModifiers() { + // TODO Auto-generated method stub + Assertions.UNREACHABLE(); + return 0; + } + + /* + * (non-Javadoc) + * + * @see com.ibm.wala.classLoader.IClass#getAllImplementedInterfaces() + */ + public Collection getAllImplementedInterfaces() { + return Collections.emptySet(); + } + + /* + * (non-Javadoc) + * + * @see com.ibm.wala.classLoader.IClass#getAllAncestorInterfaces() + */ + public Collection getAllAncestorInterfaces() { + // TODO Auto-generated method stub + Assertions.UNREACHABLE(); + return null; + } + + /* + * (non-Javadoc) + * + * @see com.ibm.wala.classLoader.IClass#getName() + */ + public TypeName getName() { + return getReference().getName(); + } + + /* + * (non-Javadoc) + * + * @see com.ibm.wala.classLoader.IClass#isReferenceType() + */ + public boolean isReferenceType() { + return getReference().isReferenceType(); + } + + /* + * (non-Javadoc) + * + * @see com.ibm.wala.classLoader.IClass#getDirectInterfaces() + */ + public Collection getDirectInterfaces() { + // TODO Auto-generated method stub + Assertions.UNREACHABLE(); + return null; + } + + public Collection getAllStaticFields() { + return getDeclaredStaticFields(); + } + + public Collection getAllFields() { + return getDeclaredStaticFields(); + } + + public Collection getAllMethods() { + return Collections.singleton(getClassInitializer()); + } +} \ No newline at end of file diff --git a/com.ibm.wala.j2ee/src/com/ibm/wala/j2ee/J2EEContextSelector.java b/com.ibm.wala.j2ee/src/com/ibm/wala/j2ee/J2EEContextSelector.java new file mode 100644 index 000000000..3a4916fd4 --- /dev/null +++ b/com.ibm.wala.j2ee/src/com/ibm/wala/j2ee/J2EEContextSelector.java @@ -0,0 +1,152 @@ +/******************************************************************************* + * 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.j2ee; + +import com.ibm.wala.analysis.reflection.JavaTypeContext; +import com.ibm.wala.analysis.typeInference.ReceiverTypeInference; +import com.ibm.wala.analysis.typeInference.ReceiverTypeInferenceCache; +import com.ibm.wala.analysis.typeInference.TypeAbstraction; +import com.ibm.wala.classLoader.CallSiteReference; +import com.ibm.wala.classLoader.IMethod; +import com.ibm.wala.ipa.callgraph.CGNode; +import com.ibm.wala.ipa.callgraph.Context; +import com.ibm.wala.ipa.callgraph.ContextSelector; +import com.ibm.wala.ipa.callgraph.propagation.InstanceKey; +import com.ibm.wala.types.ClassLoaderReference; +import com.ibm.wala.types.Descriptor; +import com.ibm.wala.types.MethodReference; +import com.ibm.wala.types.TypeName; +import com.ibm.wala.types.TypeReference; +import com.ibm.wala.util.Atom; +import com.ibm.wala.util.warnings.ResolutionFailure; +import com.ibm.wala.util.warnings.WarningSet; + +/** + * + * This class provides context selection logic for special J2EE methods. + * + * @author sfink + */ +public class J2EEContextSelector implements ContextSelector { + + private static final TypeName CacheableCommandImpl = TypeName.string2TypeName("Lcom/ibm/websphere/command/CacheableCommandImpl"); + + private static final Atom ExecuteAtom = Atom.findOrCreateAsciiAtom("execute"); + + private final static Descriptor ExecuteDesc = Descriptor.findOrCreateUTF8("()V"); + + private final static TypeReference CacheableCommandImplClass = TypeReference.findOrCreate(ClassLoaderReference.Extension, + CacheableCommandImpl); + + public final static MethodReference ExecuteMethod = MethodReference.findOrCreate(CacheableCommandImplClass, ExecuteAtom, + ExecuteDesc); + + private final ReceiverTypeInferenceCache typeInference; + + private final WarningSet warnings; + + public J2EEContextSelector(ReceiverTypeInferenceCache typeInference, WarningSet warnings) { + this.typeInference = typeInference; + this.warnings = warnings; + } + + /** + * Analyze each call to Command.execute() in a different context + * + * @see com.ibm.wala.ipa.callgraph.ContextSelector#getCalleeTarget(com.ibm.wala.ipa.callgraph.CGNode, + * com.ibm.wala.classLoader.CallSiteReference, + * com.ibm.wala.classLoader.IMethod) + */ + public Context getCalleeTarget(CGNode caller, CallSiteReference site, IMethod callee, InstanceKey receiver) { + if (callee.getReference().equals(ExecuteMethod)) { + ReceiverTypeInference R = typeInference.findOrCreate(caller); + if (R == null) { + return null; + } + TypeAbstraction type = R.getReceiverType(site); + if (type == null) { + // Type inference failed; raise a severe warning + warnings.add(ResolutionFailure.create(caller, site)); + return null; + } + return new JavaTypeContext(type); + } else { + return null; + } + } + + /* + * (non-Javadoc) + * + * @see com.ibm.wala.ipa.callgraph.ContextSelector#getBoundOnNumberOfTargets(com.ibm.wala.ipa.callgraph.CGNode, + * com.ibm.wala.classLoader.CallSiteReference, + * com.ibm.wala.classLoader.IMethod) + */ + public int getBoundOnNumberOfTargets(CGNode caller, CallSiteReference site, IMethod callee) { + + if (callee.getReference().equals(ExecuteMethod)) { + return 1; + } else { + return -1; + } + } + + /* + * (non-Javadoc) + * + * @see com.ibm.wala.ipa.callgraph.rta.RTAContextInterpreter#setWarnings(com.ibm.wala.util.warnings.WarningSet) + */ + public void setWarnings(WarningSet newWarnings) { + // this object is not bound to a WarningSet + } + + /* + * (non-Javadoc) + * + * @see com.ibm.wala.ipa.callgraph.ContextSelector#contextIsIrrelevant(com.ibm.wala.ipa.callgraph.CGNode, + * com.ibm.wala.classLoader.CallSiteReference) + */ + public boolean contextIsIrrelevant(CGNode node, CallSiteReference site) { + Atom name = site.getDeclaredTarget().getName(); + Descriptor d = site.getDeclaredTarget().getDescriptor(); + if (name.equals(ExecuteAtom) && d.equals(ExecuteDesc)) { + return false; + } else { + return true; + } + } + + /* + * (non-Javadoc) + * + * @see com.ibm.wala.ipa.callgraph.ContextSelector#allSitesDispatchIdentically(com.ibm.wala.types.MethodReference) + */ + public boolean allSitesDispatchIdentically(CGNode node, CallSiteReference site) { +// Atom name = site.getDeclaredTarget().getName(); +// Descriptor d = site.getDeclaredTarget().getDescriptor(); +// if (name.equals(ExecuteAtom) && d.equals(ExecuteDesc)) { +// return false; +// } else { +// return true; +// } + // todo: fix me + return false; + } + + public boolean mayUnderstand(CGNode caller, CallSiteReference site, IMethod targetMethod, InstanceKey instance) { + if (targetMethod.getReference().equals(ExecuteMethod)) { + return true; + } else { + return false; + } + } + +} diff --git a/com.ibm.wala.j2ee/src/com/ibm/wala/j2ee/J2EEEntrypoints.java b/com.ibm.wala.j2ee/src/com/ibm/wala/j2ee/J2EEEntrypoints.java new file mode 100644 index 000000000..4b70dec4b --- /dev/null +++ b/com.ibm.wala.j2ee/src/com/ibm/wala/j2ee/J2EEEntrypoints.java @@ -0,0 +1,90 @@ +/******************************************************************************* + * 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.j2ee; + +import java.util.Iterator; + +import com.ibm.wala.ipa.callgraph.Entrypoint; +import com.ibm.wala.ipa.callgraph.Entrypoints; +import com.ibm.wala.ipa.callgraph.impl.ComposedEntrypoints; +import com.ibm.wala.ipa.cha.ClassHierarchy; +import com.ibm.wala.util.Atom; +import com.ibm.wala.util.warnings.WarningSet; + +/** + * + * Entrypoints for an EAR file. + * + * @author sfink + */ +public class J2EEEntrypoints implements Entrypoints { + + private final static boolean USE_STRUTS_ACTIONS = true; + + private Entrypoints entrypoints; + + private final AppClientEntrypoints appClientEntrypoints; + + private final StrutsEntrypoints strutsEntrypoints; + + /** + * @param scope + * representation of the analysis scope + * @param cha + * governing class hierarchy + * @param useEjbEntrypoints + * should the analysis assume external callers on the EJB interfaces? + */ + public J2EEEntrypoints(J2EEAnalysisScope scope, DeploymentMetaData dmd, ClassHierarchy cha, WarningSet warnings, + boolean useEjbEntrypoints) { + ServletEntrypoints servletEntrypoints = new ServletEntrypoints(scope, cha); + J2EEClassTargetSelector classTargetSelector = new J2EEClassTargetSelector(null, dmd, cha, cha.getLoader(scope.getLoader(Atom + .findOrCreateUnicodeAtom("Synthetic")))); + + EJBEntrypoints ejbEntrypoints = null; + if (useEjbEntrypoints) { + // pick up all ejb entrypoints + ejbEntrypoints = new EJBEntrypoints(cha, scope, dmd, false, classTargetSelector, warnings); + } else { + // pick up only MDB EJB entrypoints + ejbEntrypoints = new EJBEntrypoints(cha, scope, dmd, true, classTargetSelector, warnings); + } + entrypoints = new ComposedEntrypoints(servletEntrypoints, ejbEntrypoints); + + appClientEntrypoints = new AppClientEntrypoints(scope, cha, warnings); + entrypoints = new ComposedEntrypoints(entrypoints, appClientEntrypoints); + + if (USE_STRUTS_ACTIONS) { + strutsEntrypoints = new StrutsEntrypoints(scope, cha); + entrypoints = new ComposedEntrypoints(entrypoints, strutsEntrypoints); + } else { + strutsEntrypoints = null; + } + } + + /* + * (non-Javadoc) + * + * @see com.ibm.wala.ipa.callgraph.Entrypoints#iterator() + */ + public Iterator iterator() { + return entrypoints.iterator(); + } + + public AppClientEntrypoints getAppClientEntrypoints() { + return appClientEntrypoints; + } + + public StrutsEntrypoints getStrutsEntrypoints() { + return strutsEntrypoints; + } + +} \ No newline at end of file diff --git a/com.ibm.wala.j2ee/src/com/ibm/wala/j2ee/J2EEMethodTargetSelector.java b/com.ibm.wala.j2ee/src/com/ibm/wala/j2ee/J2EEMethodTargetSelector.java new file mode 100644 index 000000000..6110e1ade --- /dev/null +++ b/com.ibm.wala.j2ee/src/com/ibm/wala/j2ee/J2EEMethodTargetSelector.java @@ -0,0 +1,1165 @@ +/******************************************************************************* + * 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.j2ee; + +import java.util.HashMap; +import java.util.Map; + +import com.ibm.wala.analysis.typeInference.ConeType; +import com.ibm.wala.analysis.typeInference.PointType; +import com.ibm.wala.analysis.typeInference.ReceiverTypeInference; +import com.ibm.wala.analysis.typeInference.ReceiverTypeInferenceCache; +import com.ibm.wala.analysis.typeInference.TypeAbstraction; +import com.ibm.wala.classLoader.CallSiteReference; +import com.ibm.wala.classLoader.IClass; +import com.ibm.wala.classLoader.IMethod; +import com.ibm.wala.classLoader.NewSiteReference; +import com.ibm.wala.classLoader.SyntheticMethod; +import com.ibm.wala.ipa.callgraph.AnalysisScope; +import com.ibm.wala.ipa.callgraph.CGNode; +import com.ibm.wala.ipa.callgraph.MethodTargetSelector; +import com.ibm.wala.ipa.callgraph.impl.FakeRootMethod; +import com.ibm.wala.ipa.cha.ClassHierarchy; +import com.ibm.wala.ipa.summaries.BypassSyntheticClass; +import com.ibm.wala.ipa.summaries.MethodSummary; +import com.ibm.wala.ipa.summaries.SummarizedMethod; +import com.ibm.wala.shrikeBT.BytecodeConstants; +import com.ibm.wala.shrikeBT.IInvokeInstruction; +import com.ibm.wala.ssa.SSAFieldAccessInstruction; +import com.ibm.wala.ssa.SSAGetInstruction; +import com.ibm.wala.ssa.SSAInvokeInstruction; +import com.ibm.wala.ssa.SSANewInstruction; +import com.ibm.wala.ssa.SSAPutInstruction; +import com.ibm.wala.ssa.SSAReturnInstruction; +import com.ibm.wala.ssa.SSAThrowInstruction; +import com.ibm.wala.types.ClassLoaderReference; +import com.ibm.wala.types.Descriptor; +import com.ibm.wala.types.FieldReference; +import com.ibm.wala.types.MethodReference; +import com.ibm.wala.types.TypeName; +import com.ibm.wala.types.TypeReference; +import com.ibm.wala.util.Atom; +import com.ibm.wala.util.collections.HashMapFactory; +import com.ibm.wala.util.debug.Assertions; +import com.ibm.wala.util.debug.Trace; +import com.ibm.wala.util.warnings.ResolutionFailure; +import com.ibm.wala.util.warnings.WarningSet; + +/** + * + * Special bypass rules divined from an EJB deployment descriptor. + * + * TODO: refactor this class using the delegation model + * + * @author sfink + * @author Julian Dolby (dolby@us.ibm.com) + */ +public class J2EEMethodTargetSelector implements MethodTargetSelector, BytecodeConstants, EJBConstants { + static final boolean DEBUG = false; + + private final static Atom addAtom = Atom.findOrCreateUnicodeAtom("add"); + + private final static Descriptor addDesc = Descriptor.findOrCreateUTF8("(Ljava/lang/Object;)Z"); + + private final static MethodReference addMethod = MethodReference.findOrCreate(TypeReference.JavaUtilCollection, addAtom, addDesc); + + private final static Atom elementsAtom = Atom.findOrCreateUnicodeAtom("elements"); + + private final static Descriptor elementsDesc = Descriptor.findOrCreateUTF8("()Ljava/util/Enumeration"); + + private final static MethodReference elementsMethod = MethodReference.findOrCreate(TypeReference.JavaUtilVector, elementsAtom, + elementsDesc); + + private final static MethodReference hashSetInit = MethodReference.findOrCreate(TypeReference.JavaUtilHashSet, + MethodReference.initAtom, MethodReference.defaultInitDesc); + + private final static MethodReference vectorInit = MethodReference.findOrCreate(TypeReference.JavaUtilVector, + MethodReference.initAtom, MethodReference.defaultInitDesc); + + private final static Atom JAVAX_EJB = J2EEUtil.EJB_HOME.getName().getPackage(); + + /** + * deployment information + */ + private final DeploymentMetaData deployment; + + /** + * the governing class hierarchy + */ + private final ClassHierarchy cha; + + /** + * A cache of synthetic methods generated so far. Mapping from MethodReference -> + * SyntheticMethods + */ + private final Map map = HashMapFactory.make(); + + /** + * A cache of TypeInference results + */ + private final ReceiverTypeInferenceCache typeInference; + + /** + * An object which tracks warnings from analysis + */ + private final WarningSet warnings; + + /** + * Governing analysis scope + */ + private final AnalysisScope scope; + + /** + * the method target selector to use if this one does not bypass it + */ + private final MethodTargetSelector parent; + + /** + * A mapping for EJB entity contract method names + * + * TODO: split for Home vs. Remote interfaces, etc.... + */ + private static final HashMap entityContractMap = HashMapFactory.make(10); + static { + entityContractMap.put(CREATE, new Atom[] { EJB_CREATE, EJB_POST_CREATE }); + entityContractMap.put(REMOVE, new Atom[] { EJB_REMOVE }); + entityContractMap.put(GET_PRIMARY_KEY, new Atom[] { GET_PRIMARY_KEY }); + entityContractMap.put(GET_EJB_META_DATA, new Atom[] { GET_EJB_META_DATA }); + entityContractMap.put(GET_EJB_HOME, new Atom[] { GET_EJB_HOME }); + entityContractMap.put(GET_HANDLE, new Atom[] { GET_HANDLE }); + entityContractMap.put(IS_IDENTICAL, new Atom[] { IS_IDENTICAL }); + } + + /** + * A mapping from EJB entity contract method name to classes allocated by + * these methods. + */ + private static final HashMap entityContractExceptionMap = HashMapFactory.make(5); + static { + entityContractExceptionMap.put(CREATE, CreateExceptionClass); + entityContractExceptionMap.put(REMOVE, RemoveExceptionClass); + } + + public J2EEMethodTargetSelector(AnalysisScope scope, MethodTargetSelector parent, DeploymentMetaData deployment, + ClassHierarchy cha, ReceiverTypeInferenceCache typeInference, WarningSet warnings) { + this.scope = scope; + this.deployment = deployment; + this.warnings = warnings; + this.parent = parent; + this.cha = cha; + this.typeInference = typeInference; + } + + /** + * Handle a call to an entity's remote or local interface + * + * @param m + * a call to a remote or local interface + * @return a synthetic method which serves as a target implementation for a + * call to m, or null if there's a problem + */ + private SyntheticMethod hijackEntityInterface(MethodReference m) { + if (isJavaLangObjectMethod(m)) + return null; + + if (entityContractMap.containsKey(m.getName())) { + return findOrCreateEntityContractMethod(m); + } + + TypeReference entityType = m.getDeclaringClass(); + BeanMetaData bean = deployment.getBeanForInterface(entityType); + // resolve the method via the class hierarchy first + IMethod resolved = cha.resolveMethod(m); + if (resolved == null) { + warnings.add(LoadFailure.create(m)); + return null; + } + m = resolved.getReference(); + SyntheticMethod S = map.get(m); + if (S == null) { + if (DEBUG) { + Trace.println("EJBBypass: create Synthetic case A for " + m); + } + if (Assertions.verifyAssertions) { + if (bean == null) { + Assertions._assert(false, "no bean bound for " + entityType); + } + } + IMethod ejbMethod = cha.resolveMethod(MethodReference.findOrCreate(bean.getEJBClass(), m.getName(), m.getDescriptor())); + + if (Assertions.verifyAssertions) { + Assertions._assert(ejbMethod != null, "Could not find method " + bean.getEJBClass() + " " + m.getName() + " " + + m.getDescriptor()); + } + + MethodSummary summ = new MethodSummary(m); + int nextLocal = summ.getNumberOfParameters() + 1; + + // 1. extract bean object from container object + // TODO: we pretend that the Entity is stateless, which it is not. + int beanVN = nextLocal++; + summ.addStatement(new SSAGetInstruction(beanVN, J2EEContainerModel.getBeanFieldRef(bean))); + + // 2. call corresponding method on bean object + int EXCEPTION_VN = nextLocal++; + int returnVN = nextLocal++; + + int[] params = new int[summ.getNumberOfParameters()]; + params[0] = beanVN; + for (int i = 1; i < params.length; i++) { + params[i] = i + 1; + } + + MethodReference ref = ejbMethod.getReference(); + CallSiteReference site = CallSiteReference.make(summ.getNextProgramCounter(), ref, IInvokeInstruction.Dispatch.VIRTUAL); + + if (summ.getReturnType() != null) { + summ.addStatement(new SSAInvokeInstruction(returnVN, params, EXCEPTION_VN, site)); + summ.addStatement(new SSAReturnInstruction(returnVN, summ.getReturnType().isPrimitiveType())); + } else { + summ.addStatement(new SSAInvokeInstruction(params, EXCEPTION_VN, site)); + } + + // 3. throw RemoteException if remote interface + if (deployment.isRemoteInterface(m.getDeclaringClass())) { + int xobj = nextLocal++; + summ.addStatement(new SSANewInstruction(xobj, NewSiteReference.make(summ.getNextProgramCounter(), RemoteExceptionClass))); + summ.addStatement(new SSAThrowInstruction(xobj)); + } + + int xobj = nextLocal++; + summ.addStatement(new SSANewInstruction(xobj, NewSiteReference.make(summ.getNextProgramCounter(), EJBExceptionClass))); + summ.addStatement(new SSAThrowInstruction(xobj)); + + IClass C = cha.lookupClass(m.getDeclaringClass()); + S = new SummarizedEJBMethod(bean, m, summ, C); + map.put(m, S); + } + + if (DEBUG) { + Trace.println("EJBBypass: case A return " + S); + } + return S; + } + + /** + * TODO: refactor extract common code with other hijack methods + * + * @param m + * @return a Synthetic method representing the a container-implemented method + * for the onMessage MDB entrypoint + */ + private SyntheticMethod hijackOnMessageEntrypoint(MethodReference m) { + + TypeReference mdbType = m.getDeclaringClass(); + BeanMetaData bean = deployment.getBeanMetaData(mdbType); + // resolve the method via the class hierarchy first + IMethod resolved = cha.resolveMethod(m); + if (resolved == null) { + warnings.add(LoadFailure.create(m)); + return null; + } + m = resolved.getReference(); + SyntheticMethod S = map.get(m); + if (S == null) { + if (DEBUG) { + Trace.println("EJBBypass: create Synthetic case A for " + m); + } + if (Assertions.verifyAssertions) { + if (bean == null) { + Assertions._assert(false, "no bean bound for " + mdbType); + } + } + MethodSummary summ = new MethodSummary(m); + int nextLocal = summ.getNumberOfParameters() + 1; + + // 1. extract bean object from container object + // TODO: we pretend that the Entity is stateless, which it is not. + int beanVN = nextLocal++; + summ.addStatement(new SSAGetInstruction(beanVN, J2EEContainerModel.getBeanFieldRef(bean))); + + // 2. call corresponding method on bean object + int EXCEPTION_VN = nextLocal++; + int returnVN = nextLocal++; + + int[] params = new int[summ.getNumberOfParameters()]; + params[0] = beanVN; + for (int i = 1; i < params.length; i++) { + params[i] = i + 1; + } + + MethodReference ref = resolved.getReference(); + CallSiteReference site = CallSiteReference.make(summ.getNextProgramCounter(), ref, IInvokeInstruction.Dispatch.VIRTUAL); + + if (summ.getReturnType() != null) { + summ.addStatement(new SSAInvokeInstruction(returnVN, params, EXCEPTION_VN, site)); + summ.addStatement(new SSAReturnInstruction(returnVN, summ.getReturnType().isPrimitiveType())); + } else { + summ.addStatement(new SSAInvokeInstruction(params, EXCEPTION_VN, site)); + } + + // 3. throw RemoteException if remote interface + if (deployment.isRemoteInterface(m.getDeclaringClass())) { + int xobj = nextLocal++; + summ.addStatement(new SSANewInstruction(xobj, NewSiteReference.make(summ.getNextProgramCounter(), RemoteExceptionClass))); + summ.addStatement(new SSAThrowInstruction(xobj)); + } + + int xobj = nextLocal++; + summ.addStatement(new SSANewInstruction(xobj, NewSiteReference.make(summ.getNextProgramCounter(), EJBExceptionClass))); + summ.addStatement(new SSAThrowInstruction(xobj)); + + IClass C = cha.lookupClass(m.getDeclaringClass()); + S = new SummarizedEJBMethod(bean, m, summ, C); + map.put(m, S); + } + + if (DEBUG) { + Trace.println("EJBBypass: case A return " + S); + } + return S; + } + + /** + * @param m + * @return a Synthetic method representing a servlet entrypoint to call + */ + private SyntheticMethod hijackServletEntrypoint(MethodReference m) { + + SyntheticMethod S = map.get(m); + if (S == null) { + MethodSummary summ = new MethodSummary(m); + int nextLocal = summ.getNumberOfParameters() + 1; + + int EXCEPTION_VN = nextLocal++; + int returnVN = nextLocal++; + + // allocate a ServletConfig object + if (!m.getDeclaringClass().getClassLoader().equals(ClassLoaderReference.Primordial)) { + int servletConfigVN = nextLocal++; + NewSiteReference newConfig = NewSiteReference.make(summ.getNextProgramCounter(), ServletEntrypoints.WalaServletConfigModel); + summ.addStatement(new SSANewInstruction(servletConfigVN, newConfig)); + + // initialize the servlet + CallSiteReference site = CallSiteReference.make(summ.getNextProgramCounter(), ServletEntrypoints.servletInit, + IInvokeInstruction.Dispatch.INTERFACE); + int[] params = new int[2]; + params[0] = 1; // "this" pointer + params[1] = servletConfigVN; + summ.addStatement(new SSAInvokeInstruction(params, EXCEPTION_VN, site)); + } + + int[] params = new int[summ.getNumberOfParameters()]; + params[0] = 1; // "this" pointer + for (int i = 1; i < params.length; i++) { + params[i] = i + 1; + } + // invoke the desired entrypoint + CallSiteReference site = CallSiteReference.make(summ.getNextProgramCounter(), m, IInvokeInstruction.Dispatch.VIRTUAL); + if (summ.getReturnType() != null) { + summ.addStatement(new SSAInvokeInstruction(returnVN, params, EXCEPTION_VN, site)); + summ.addStatement(new SSAReturnInstruction(returnVN, summ.getReturnType().isPrimitiveType())); + } else { + summ.addStatement(new SSAInvokeInstruction(params, EXCEPTION_VN, site)); + } + + IClass C = cha.lookupClass(m.getDeclaringClass()); + S = new SummarizedMethod(m, summ, C); + map.put(m, S); + } + + return S; + } + + /** + * Handle a call to an entity's home or local home + * + * @param m + * a call to a home or local home interface + * @return a synthetic method which serves as a target implementation for a + * call to m + */ + private SyntheticMethod hijackHomeInterface(MethodReference m) { + if (isJavaLangObjectMethod(m)) + return null; + + TypeReference type = m.getDeclaringClass(); + IClass C = cha.lookupClass(type); + BeanMetaData bean = deployment.getBeanForInterface(type); + if (Assertions.verifyAssertions) { + Assertions._assert(bean != null, "null bean for " + type); + } + boolean local = deployment.isLocalHomeInterface(type); + + if (deployment.isFinder(m)) { + MethodSummary summ = (local) ? new LocalHomeFinderSummary(m) : new RemoteFinderSummary(m); + SummarizedEJBMethod S = new SummarizedEJBMethod(bean, m, summ, C); + map.put(m, S); + return S; + } else if (entityContractMap.containsKey(m.getName())) { + return findOrCreateEntityContractMethod(m); + } else if (isHomeMethod(m, bean)) { + MethodSummary summ = new HomeMethodSummary(m, bean); + SummarizedEJBMethod S = new SummarizedEJBMethod(bean, m, summ, C); + map.put(m, S); + return S; + } else + return null; + } + + /** + * Handle a call to a CMP or CMR getter or setter + * + * @param m + * a call to a CMP or CMR getter of setter + * @return a synthetic method which serves as a target implementation for a + * call to m + */ + private SyntheticMethod hijackCMPBeanMethods(MethodReference m) { + + TypeReference type = m.getDeclaringClass(); + BeanMetaData bean = deployment.getBeanForInterface(type); + SyntheticMethod S = null; + if (deployment.isCMPGetter(m)) { + // get declaring instance from class hierarchy + m = cha.resolveMethod(m).getReference(); + // return a summary for a CMP getter + S = map.get(m); + if (S == null) { + if (deployment.isCMRGetter(m)) { + CMRGetterSummary g = new CMRGetterSummary(m); + S = createSummarizedMethod(bean, m, g); + } else { + GetterSummary g = new GetterSummary(m); + S = createSummarizedMethod(bean, m, g); + } + } + return S; + } else if (deployment.isCMPSetter(m)) { + // get declaring instance from class hierarchy + m = cha.resolveMethod(m).getReference(); + // return a summary for CMP setter + S = map.get(m); + if (S == null) { + if (deployment.isCMRSetter(m)) { + CMRSetterSummary s = new CMRSetterSummary(m); + S = createSummarizedMethod(bean, m, s); + } else { + SetterSummary s = new SetterSummary(m); + S = createSummarizedMethod(bean, m, s); + } + } + return S; + } else + return null; + } + + /** + * If m is a special EJB-container generated method, return the IMethod that + * represents the modelled target of a call to m. Else, return null; + */ + private SyntheticMethod methodReferenceIntercept(MethodReference m) { + TypeReference type = m.getDeclaringClass(); + if (DEBUG) { + Trace.println("EJBBypass: intercept? " + m); + } + + if (type.getClassLoader().equals(ClassLoaderReference.Primordial)) { + // small optimization: we know we will never hijack calls to the + // primordial loader + return null; + } + + if (deployment.isLocalInterface(type) || deployment.isRemoteInterface(type)) { + return hijackEntityInterface(m); + } else if (deployment.isLocalHomeInterface(type) || deployment.isHomeInterface(type)) { + return hijackHomeInterface(m); + } else if (deployment.isContainerManaged(type)) { + return hijackCMPBeanMethods(m); + } else { + return null; + } + } + + private boolean isJavaLangObjectMethod(MethodReference m) { + IClass object = cha.lookupClass(TypeReference.JavaLangObject); + IMethod declaredMethod = object.getMethod(m.getSelector()); + return declaredMethod != null; + } + + private SyntheticMethod createSummarizedMethod(BeanMetaData bean, MethodReference m, MethodSummary g) { + IClass C = cha.lookupClass(m.getDeclaringClass()); + SyntheticMethod S = new SummarizedEJBMethod(bean, m, g, C); + map.put(m, S); + return S; + } + + /** + * @param m + * @return a Synthetic method representing the a container-implemented method + * for the EJB Entity contract + */ + private SyntheticMethod findOrCreateEntityContractMethod(MethodReference m) { + if (DEBUG) { + Trace.println("findOrCreateEntityContractMethod " + m); + } + SyntheticMethod S = map.get(m); + if (S == null) { + + TypeReference rType = m.getReturnType(); + TypeReference receiverType = m.getDeclaringClass(); + IClass receiverClass = cha.lookupClass(receiverType); + BeanMetaData bean = deployment.getBeanForInterface(receiverType); + TypeReference ejbType = bean.getEJBClass(); + IClass ejbClass = cha.lookupClass(ejbType); + + MethodSummary summ = new MethodSummary(m); + int nextLocal = summ.getNumberOfParameters() + 1; + + // get ejb object from pool + int alloc = nextLocal++; + summ.addStatement(new SSAGetInstruction(alloc, J2EEContainerModel.getBeanFieldRef(bean))); + + // create+return entity object, if appropriate + if (rType != TypeReference.Void) { + + // create result object + int ret = nextLocal++; + summ.addStatement(new SSANewInstruction(ret, NewSiteReference.make(summ.getNextProgramCounter(), rType))); + + // return it + summ.addStatement(new SSAReturnInstruction(ret, false)); + } + + // call contract methods + Atom[] names = entityContractMap.get(m.getName()); + for (int i = 0; i < names.length; i++) { + Atom name = names[i]; + MethodReference ref = makeEntityContractMethod(bean, m, ejbType, name); + CallSiteReference site = CallSiteReference.make(summ.getNextProgramCounter(), ref, ejbClass.isInterface() ? IInvokeInstruction.Dispatch.INTERFACE + : IInvokeInstruction.Dispatch.VIRTUAL); + if (cha.resolveMethod(ejbClass, ref.getSelector()) == null) + continue; + int[] params = new int[summ.getNumberOfParameters()]; + // set up the dispatch to the bean object + params[0] = alloc; + for (int j = 1; j < params.length; j++) { + params[j] = j + 1; + } + // note that we reserve value number 2 to hold the exceptional result + // of the call. + if (!ref.getReturnType().equals(TypeReference.Void)) { + summ.addStatement(new SSAInvokeInstruction(nextLocal++, params, nextLocal++, site)); + } else { + summ.addStatement(new SSAInvokeInstruction(params, nextLocal++, site)); + } + } + + final TypeReference t = entityContractExceptionMap.get(m.getName()); + if (t != null) { + int ex = nextLocal++; + summ.addStatement(new SSANewInstruction(ex, NewSiteReference.make(summ.getNextProgramCounter(), t))); + summ.addStatement(new SSAThrowInstruction(ex)); + } + + if (deployment.isRemoteInterface(m.getDeclaringClass()) || deployment.isHomeInterface(m.getDeclaringClass())) { + int xobj = nextLocal++; + summ.addStatement(new SSANewInstruction(xobj, NewSiteReference.make(summ.getNextProgramCounter(), RemoteExceptionClass))); + summ.addStatement(new SSAThrowInstruction(xobj)); + } + + int ejbException = nextLocal++; + summ + .addStatement(new SSANewInstruction(ejbException, NewSiteReference.make(summ.getNextProgramCounter(), EJBExceptionClass))); + summ.addStatement(new SSAThrowInstruction(ejbException)); + + S = new SummarizedMethod(m, summ, receiverClass); + map.put(m, S); + } + return S; + } + + /** + * @param bean + * metadata regarding the EJB + * @param ifaceMethod + * name of a method called on an EJB interface + * @param ejbType + * concrete type the method should dispatch to + * @param methodName + * name of the bean method to dispatch to + * @return a method reference representing the dispatch target + */ + private MethodReference makeEntityContractMethod(BeanMetaData bean, MethodReference ifaceMethod, TypeReference ejbType, + Atom methodName) { + if (Assertions.verifyAssertions) { + Assertions._assert(bean != null); + } + TypeName returnType = TypeReference.VoidName; + if (methodName.equals(EJB_CREATE) && bean.isContainerManagedEntity()) { + // ejbCreate returns the primary key type. + returnType = bean.getPrimaryKeyType().getName(); + } + MethodReference ref = MethodReference.findOrCreate(ejbType, methodName, Descriptor.findOrCreate(ifaceMethod.getDescriptor() + .getParameters(), returnType)); + return ref; + } + + private class GetterSummary extends MethodSummary { + public GetterSummary(final MethodReference method) { + super(method); + FieldReference field = deployment.getCMPField(method); + int nextLocal = 2; + TypeReference T = field.getFieldType(); + if (T.isReferenceType()) { + T = cha.lookupClass(T).getReference(); + } + + // the reference dispatched on is value number 1, and + // we store the result in value number nextLocal++ + + // TODO: we should make sure that finders populate all fields. + int result = nextLocal++; + SSAFieldAccessInstruction f = new SSAGetInstruction(result, 1, field); + addStatement(f); + + SSAReturnInstruction r = new SSAReturnInstruction(result, field.getFieldType().isPrimitiveType()); + addStatement(r); + + if (deployment.isRemoteInterface(method.getDeclaringClass())) { + int xobj = nextLocal++; + addStatement(new SSANewInstruction(xobj, NewSiteReference.make(getNextProgramCounter(), RemoteExceptionClass))); + addStatement(new SSAThrowInstruction(xobj)); + } + int xobj = nextLocal++; + addStatement(new SSANewInstruction(xobj, NewSiteReference.make(getNextProgramCounter(), EJBExceptionClass))); + addStatement(new SSAThrowInstruction(xobj)); + } + } + + /** + * A synthetic model of a CMR getter method + */ + private class CMRGetterSummary extends MethodSummary { + public CMRGetterSummary(final MethodReference method) { + super(method); + FieldReference field = deployment.getCMPField(method); + int nextLocal = 2; + TypeReference T = field.getFieldType(); + T = cha.lookupClass(T).getReference(); + + BeanMetaData getteeBean = deployment.getCMRBean(field); + TypeReference getteeType = getteeBean.getLocalInterface(); + TypeReference getteeHomeType = getteeBean.getLocalHomeInterface(); + TypeReference keyType = getteeBean.getPrimaryKeyType(); + + Atom finderName = Atom.findOrCreateUnicodeAtom("findByPrimaryKey"); + Descriptor finderDesc = Descriptor.findOrCreate(new TypeName[] { keyType.getName() }, getteeType.getName()); + IMethod finder = cha.resolveMethod(MethodReference.findOrCreate(getteeHomeType, finderName, finderDesc)); + if (finder == null) { + // Here's a bad kludge ... it appears that the primary key type might be + // a subclass of the + // argument of the descriptor. TODO: figure out how this happens. + // temp fix: Try Ojbect instead ... + finderDesc = Descriptor.findOrCreate(new TypeName[] { TypeReference.JavaLangObject.getName() }, getteeType.getName()); + finder = cha.resolveMethod(MethodReference.findOrCreate(getteeHomeType, finderName, finderDesc)); + if (Assertions.verifyAssertions) { + Assertions._assert(finder != null, "failed to find findByPrimaryKey for " + getteeType); + } + } + + // allocate type of primary key + // TODO: should probably pretend the object has a field of this type + NewSiteReference nsr = NewSiteReference.make(getNextProgramCounter(), keyType); + int keyAlloc = nextLocal++; + addStatement(new SSANewInstruction(keyAlloc, nsr)); + + // allocate local home type + // TODO: this is fake; should model container providing home somehow + NewSiteReference lhnr = NewSiteReference.make(getNextProgramCounter(), getteeHomeType); + int localHomeAlloc = nextLocal++; + addStatement(new SSANewInstruction(localHomeAlloc, lhnr)); + + // call findByPrimaryKey + int fr = nextLocal++; + int ignoredExceptions = nextLocal++; + CallSiteReference fcsr = CallSiteReference.make(getNextProgramCounter(), finder.getReference(), IInvokeInstruction.Dispatch.INTERFACE); + addStatement(new SSAInvokeInstruction(fr, new int[] { localHomeAlloc, keyAlloc }, ignoredExceptions, fcsr)); + + // return result, as set if appropriate + if (T.equals(TypeReference.JavaUtilSet) || T.equals(TypeReference.JavaUtilCollection)) { + // assume HashSet is the type of the returned collection. + int setObj = nextLocal++; + NewSiteReference setRef = NewSiteReference.make(getNextProgramCounter(), TypeReference.JavaUtilHashSet); + SSANewInstruction n = new SSANewInstruction(setObj, setRef); + addStatement(n); + + int initIgnoredExceptions = nextLocal++; + CallSiteReference initRef = CallSiteReference.make(getNextProgramCounter(), hashSetInit, IInvokeInstruction.Dispatch.SPECIAL); + addStatement(new SSAInvokeInstruction(new int[] { setObj }, initIgnoredExceptions, initRef)); + + int ignoredResult = nextLocal++; + int moreIgnoredExceptions = nextLocal++; + CallSiteReference addRef = CallSiteReference.make(getNextProgramCounter(), addMethod, IInvokeInstruction.Dispatch.INTERFACE); + SSAInvokeInstruction addCall = new SSAInvokeInstruction(ignoredResult, new int[] { setObj, fr }, moreIgnoredExceptions, + addRef); + addStatement(addCall); + + SSAReturnInstruction r = new SSAReturnInstruction(setObj, false); + addStatement(r); + } else { + + SSAReturnInstruction r = new SSAReturnInstruction(fr, false); + addStatement(r); + } + + // put in a bogus getfield to pacify old clients that expect + // to see a getfield here. TODO: rewrite the old clients to + // avoid needing this instruction. + int ignore = nextLocal++; + SSAFieldAccessInstruction f = new SSAGetInstruction(ignore, 1, field); + addStatement(f); + + if (deployment.isRemoteInterface(method.getDeclaringClass())) { + int xobj = nextLocal++; + addStatement(new SSANewInstruction(xobj, NewSiteReference.make(getNextProgramCounter(), RemoteExceptionClass))); + addStatement(new SSAThrowInstruction(xobj)); + } + int xobj = nextLocal++; + addStatement(new SSANewInstruction(xobj, NewSiteReference.make(getNextProgramCounter(), EJBExceptionClass))); + addStatement(new SSAThrowInstruction(xobj)); + } + } + + /** + * A synthetic model of a CMP setter method + */ + private class SetterSummary extends MethodSummary { + public SetterSummary(final MethodReference method) { + super(method); + // the reference dispatched on is value number 1, and + // the value stored is value number 2 + SSAFieldAccessInstruction f = new SSAPutInstruction(1, 2, deployment.getCMPField(method)); + addStatement(f); + } + } + + /** + * A synthetic model of a CMR setter method + */ + private class CMRSetterSummary extends MethodSummary { + public CMRSetterSummary(final MethodReference method) { + super(method); + // the reference dispatched on is value number 1, and + // the value stored is value number 2 + FieldReference field = deployment.getCMPField(method); + TypeReference T = field.getFieldType(); + int nextLocal = 3; + T = cha.lookupClass(T).getReference(); + if (T.equals(TypeReference.JavaUtilSet) || T.equals(TypeReference.JavaUtilCollection)) { + // assume HashSet is the type of the returned collection. + int setObj = nextLocal++; + NewSiteReference setRef = NewSiteReference.make(getNextProgramCounter(), TypeReference.JavaUtilHashSet); + SSANewInstruction allocSet = new SSANewInstruction(setObj, setRef); + addStatement(allocSet); + + int initIgnoredExceptions = nextLocal++; + CallSiteReference initRef = CallSiteReference.make(getNextProgramCounter(), hashSetInit, IInvokeInstruction.Dispatch.SPECIAL); + addStatement(new SSAInvokeInstruction(new int[] { setObj }, initIgnoredExceptions, initRef)); + + int ignoredResult = nextLocal++; + int moreIgnoredExceptions = nextLocal++; + CallSiteReference addRef = CallSiteReference.make(getNextProgramCounter(), addMethod,IInvokeInstruction.Dispatch.INTERFACE); + SSAInvokeInstruction addCall = new SSAInvokeInstruction(ignoredResult, new int[] { setObj, 2 }, moreIgnoredExceptions, + addRef); + addStatement(addCall); + + SSAFieldAccessInstruction f2 = new SSAPutInstruction(1, setObj, field); + addStatement(f2); + } else { + SSAFieldAccessInstruction f2 = new SSAPutInstruction(1, 2, field); + addStatement(f2); + } + + // create a bogus instance of the the bean on the other side + // of the relationship. TODO: is it OK to use the local interface? + // perhaps sometimes should use the remote interface ... + + BeanMetaData otherBean = deployment.getCMRBean(field); + TypeReference otherType = otherBean.getLocalInterface(); + NewSiteReference newRef = NewSiteReference.make(getNextProgramCounter(), otherType); + int otherInstance = nextLocal++; + SSANewInstruction n = new SSANewInstruction(otherInstance, newRef); + addStatement(n); + + // model a putfield on the other instance + // TODO: for now it doesn't matter what we shove in this field ... since + // when we call the getter we'll return a synthetic answer. + // fix this if and when it becomes a problem. + FieldReference oppField = deployment.getOppositeField(field); + if (oppField == null) { + // this is a problem ... the field is not navigable .... need to do + // something better, like + // create a synthetic field. + warnings.add(LoadFailure.create(field)); + return; + } + TypeReference otherT = oppField.getFieldType(); + otherT = cha.lookupClass(otherT).getReference(); + if (otherT.equals(TypeReference.JavaUtilSet) || otherT.equals(TypeReference.JavaUtilCollection)) { + // assume HashSet is the type of the returned collection. + int setObj = nextLocal++; + NewSiteReference setRef = NewSiteReference.make(getNextProgramCounter(), TypeReference.JavaUtilHashSet); + SSANewInstruction allocSet = new SSANewInstruction(setObj, setRef); + addStatement(allocSet); + + int initIgnoredExceptions = nextLocal++; + CallSiteReference initRef = CallSiteReference.make(getNextProgramCounter(), hashSetInit, IInvokeInstruction.Dispatch.SPECIAL); + addStatement(new SSAInvokeInstruction(new int[] { setObj }, initIgnoredExceptions, initRef)); + + int ignoredResult = nextLocal++; + int moreIgnoredExceptions = nextLocal++; + CallSiteReference addRef = CallSiteReference.make(getNextProgramCounter(), addMethod,IInvokeInstruction.Dispatch.INTERFACE); + SSAInvokeInstruction addCall = new SSAInvokeInstruction(ignoredResult, new int[] { setObj, 1 }, moreIgnoredExceptions, + addRef); + addStatement(addCall); + + SSAFieldAccessInstruction f2 = new SSAPutInstruction(otherInstance, setObj, oppField); + addStatement(f2); + } else { + SSAFieldAccessInstruction f2 = new SSAPutInstruction(otherInstance, 1, oppField); + addStatement(f2); + } + } + } + + private boolean isHomeMethod(MethodReference method, BeanMetaData bean) { + TypeReference ejbType = bean.getEJBClass(); + IClass ejbClass = cha.lookupClass(ejbType); + + Atom newName = Atom.findOrCreateUnicodeAtom("ejb" + method.getName().toString()); + + TypeReference rType = method.getReturnType(); + + // call approriate method + MethodReference ref = MethodReference.findOrCreate(ejbType, newName, Descriptor.findOrCreate(method.getDescriptor() + .getParameters(), rType.getName())); + + return cha.resolveMethod(ejbClass, ref.getSelector()) != null; + } + + /** + * model for a user-defined method on a home or local home interface + */ + private class HomeMethodSummary extends MethodSummary { + /** + * @param method + * the interface method summarized + */ + public HomeMethodSummary(MethodReference method, BeanMetaData bean) { + super(method); + TypeReference ejbType = bean.getEJBClass(); + IClass ejbClass = cha.lookupClass(ejbType); + + Atom newName = Atom.findOrCreateUnicodeAtom("ejb" + method.getName().toString()); + int nextLocal = getNumberOfParameters() + 1; + + // get ejb object from pool + int ejbObject = nextLocal++; + addStatement(new SSAGetInstruction(ejbObject, J2EEContainerModel.getBeanFieldRef(bean))); + + TypeReference rType = method.getReturnType(); + + // call approriate method + MethodReference ref = MethodReference.findOrCreate(ejbType, newName, Descriptor.findOrCreate(method.getDescriptor() + .getParameters(), rType.getName())); + CallSiteReference site = CallSiteReference.make(getNextProgramCounter(), ref, IInvokeInstruction.Dispatch.VIRTUAL); + if (cha.resolveMethod(ejbClass, ref.getSelector()) == null) { + return; + } + + int[] params = new int[getNumberOfParameters()]; + // set up the dispatch to the bean object + params[0] = ejbObject; + for (int j = 1; j < params.length; j++) { + params[j] = j + 1; + } + // note that we reserve a value number to hold the exceptional result + // of the call. + if (rType.equals(TypeReference.Void)) { + addStatement(new SSAInvokeInstruction(params, nextLocal++, site)); + } else { + int ret = nextLocal++; + addStatement(new SSAInvokeInstruction(ret, params, nextLocal++, site)); + addStatement(new SSAReturnInstruction(ret, rType.isPrimitiveType())); + } + + } + } + + // TODO!!! I think a finder really should may populate each field + // in the found object. Probably should create a Hydrate method + // summary for this. + private class LocalHomeFinderSummary extends MethodSummary { + protected int nextLocal; + + public LocalHomeFinderSummary(final MethodReference method) { + super(method); + + nextLocal = method.getNumberOfParameters() + 2; + TypeReference rType = cha.lookupClass(method.getReturnType()).getReference(); + TypeReference homeType = method.getDeclaringClass(); + TypeReference beanType = deployment.getFinderBeanType(method); + BeanMetaData beanData = deployment.getBeanMetaData(beanType); + TypeReference entType = (deployment.isLocalHomeInterface(homeType) ? beanData.getLocalInterface() : beanData + .getRemoteInterface()); + + // create interface object + int result2 = nextLocal++; + NewSiteReference ref2 = NewSiteReference.make(getNextProgramCounter(), entType); + SSANewInstruction a2 = new SSANewInstruction(result2, ref2); + addStatement(a2); + + if (rType.equals(TypeReference.JavaUtilCollection) || rType.equals(TypeReference.JavaUtilSet)) { + // assume that the finder returns a HashSet + int result3 = nextLocal++; + NewSiteReference ref3 = NewSiteReference.make(getNextProgramCounter(), TypeReference.JavaUtilHashSet); + SSANewInstruction a3 = new SSANewInstruction(result3, ref3); + addStatement(a3); + + int initIgnoredExceptions = nextLocal++; + CallSiteReference initRef = CallSiteReference.make(getNextProgramCounter(), hashSetInit, IInvokeInstruction.Dispatch.SPECIAL); + addStatement(new SSAInvokeInstruction(new int[] { result3 }, initIgnoredExceptions, initRef)); + + int ignoredResult = nextLocal++; + int ignoredExceptions = nextLocal++; + CallSiteReference addRef = CallSiteReference.make(getNextProgramCounter(), addMethod, IInvokeInstruction.Dispatch.INTERFACE); + SSAInvokeInstruction addCall = new SSAInvokeInstruction(ignoredResult, new int[] { result3, result2 }, ignoredExceptions, + addRef); + addStatement(addCall); + + SSAReturnInstruction r = new SSAReturnInstruction(result3, false); + addStatement(r); + } else if (rType.equals(TypeReference.JavaUtilEnum)) { + int result3 = nextLocal++; + NewSiteReference ref3 = NewSiteReference.make(getNextProgramCounter(), TypeReference.JavaUtilVector); + SSANewInstruction a3 = new SSANewInstruction(result3, ref3); + addStatement(a3); + + int initIgnoredExceptions = nextLocal++; + CallSiteReference initRef = CallSiteReference.make(getNextProgramCounter(), vectorInit, IInvokeInstruction.Dispatch.SPECIAL); + addStatement(new SSAInvokeInstruction(new int[] { result3 }, initIgnoredExceptions, initRef)); + + int ignoredResult = nextLocal++; + int ignoredExceptions = nextLocal++; + CallSiteReference addRef = CallSiteReference.make(getNextProgramCounter(), addMethod, IInvokeInstruction.Dispatch.INTERFACE); + SSAInvokeInstruction addCall = new SSAInvokeInstruction(ignoredResult, new int[] { result3, result2 }, ignoredExceptions, + addRef); + addStatement(addCall); + + int result4 = nextLocal++; + int moreIgnoredExceptions = nextLocal++; + CallSiteReference elementsRef = CallSiteReference.make(getNextProgramCounter(), elementsMethod, IInvokeInstruction.Dispatch.VIRTUAL); + SSAInvokeInstruction elementsCall = new SSAInvokeInstruction(result4, new int[] { result3 }, moreIgnoredExceptions, + elementsRef); + addStatement(elementsCall); + + SSAReturnInstruction r = new SSAReturnInstruction(result4, false); + addStatement(r); + } else { + int xobj = nextLocal++; + addStatement(new SSANewInstruction(xobj, NewSiteReference.make(getNextProgramCounter(), ObjectNotFoundExceptionClass))); + addStatement(new SSAThrowInstruction(xobj)); + + SSAReturnInstruction r = new SSAReturnInstruction(result2, false); + addStatement(r); + } + + int xobj2 = nextLocal++; + addStatement(new SSANewInstruction(xobj2, NewSiteReference.make(getNextProgramCounter(), FinderExceptionClass))); + addStatement(new SSAThrowInstruction(xobj2)); + + int xobj3 = nextLocal++; + addStatement(new SSANewInstruction(xobj3, NewSiteReference.make(getNextProgramCounter(), EJBExceptionClass))); + addStatement(new SSAThrowInstruction(xobj3)); + + } + } + + private class RemoteFinderSummary extends LocalHomeFinderSummary { + public RemoteFinderSummary(final MethodReference method) { + super(method); + + int xobj = nextLocal++; + addStatement(new SSANewInstruction(xobj, NewSiteReference.make(getNextProgramCounter(), RemoteExceptionClass))); + addStatement(new SSAThrowInstruction(xobj)); + + } + } + + /* + * (non-Javadoc) + * + * @see com.ibm.wala.ipa.cha.MethodBypass#getBypass(com.ibm.wala.classLoader.MethodReference) + */ + public IMethod getCalleeTarget(CGNode N, CallSiteReference site, IClass receiver) { + MethodReference m = site.getDeclaredTarget(); + + // If the declared target is something generic like EJBObject, perform + // type inference to try and resolve a more specific bean receiver for + // this call. + if (isEJBSuperInterface(m.getDeclaringClass())) { + IClass inferred = getReceiverClassFromTypeInference(N, site); + if (inferred != null) { + receiver = inferred; + } + } + + // special logic for MDB onMessage entrypoints + if (FakeRootMethod.isFakeRootMethod(N.getMethod().getReference())) { + if (deployment.isMessageDriven(m.getDeclaringClass())) { + if (m.getName().equals(onMessageAtom) && m.getDescriptor().equals(onMessageDesc)) { + return hijackOnMessageEntrypoint(m); + } + } + // special logic for servlet entrypoints + else if (receiver != null && cha.implementsInterface(receiver, ServletEntrypoints.Servlet)) { + IMethod resolved = cha.resolveMethod(receiver, m.getSelector()); + if (!resolved.isInit() && !resolved.isClinit()) { + return hijackServletEntrypoint(m); + } + } + } + + // encode the receiver type in the method reference m + m = specializeForReceiverType(receiver, m); + + // first try to intercept the call before delegating + // [SJF]: I don't think this should be necessary ... let the delegate go ... + // we'll clean up later anyway. + // update ... it seems this is necessary to pass the AutoProfile + // ATKTest ... leave it in for now. + SyntheticMethod X = methodReferenceIntercept(m); + if (X != null) { + return X; + } + + // now delegate + IMethod target = parent.getCalleeTarget(N, site, receiver); + if (target == null) { + return null; + } + + // delegation is done ... try to intercept now. + X = methodReferenceIntercept(target.getReference()); + if (X != null) { + return X; + } else { + return target; + } + } + + /** + * @param receiver + * @param m + * @return a method reference based on m, but encoding the receiver as the + * declared class ... or m is receiver is null + */ + private MethodReference specializeForReceiverType(IClass receiver, MethodReference m) { + // create a MethodReference m which encodes the receiver type. + if (receiver != null) { + if (receiver.getClassLoader().getReference().equals(scope.getSyntheticLoader())) { + if (receiver instanceof BypassSyntheticClass) + return MethodReference.findOrCreate(((BypassSyntheticClass) receiver).getRealType().getReference(), m.getName(), m + .getDescriptor()); + else + return MethodReference.findOrCreate(receiver.getReference(), m.getName(), m.getDescriptor()); + } else { + return MethodReference.findOrCreate(receiver.getReference(), m.getName(), m.getDescriptor()); + } + } + return m; + } + + /** + * @param N + * governing node + * @param site + * a call to something generic like EJBObject + * @return an estimate for the receiver class based on local type inference, + * or null if type inference doesn't help + */ + private IClass getReceiverClassFromTypeInference(CGNode N, CallSiteReference site) { + ReceiverTypeInference R = typeInference.findOrCreate(N); + TypeAbstraction type = null; + if (R != null) { + type = R.getReceiverType(site); + } + if (type == null) { + // Type inference failed; raise a severe warning + warnings.add(ResolutionFailure.create(N, site)); + return null; + } else { + // Type inference succeeded; modify m to reflect the more specific + // receiver + if (type instanceof PointType) { + return ((PointType) type).getType(); + } else if (type instanceof ConeType) { + return ((ConeType) type).getType(); + } else { + Assertions.UNREACHABLE("Unexpected type" + type); + return null; + } + } + } + + /** + * @param T + * @return true iff T is one of the EJB Superinterfaces defined in J2EEUtil + */ + private boolean isEJBSuperInterface(TypeReference T) { + TypeName tName = T.getName(); + Atom pack = tName.getPackage(); + if (pack == null || !pack.equals(JAVAX_EJB)) { + return false; + } + + IClass klass = cha.lookupClass(T); + if (klass == null) { + return false; + } else { + TypeReference k = klass.getReference(); + return (k.equals(J2EEUtil.EJB_HOME) || k.equals(J2EEUtil.EJB_LOCAL_HOME) || k.equals(J2EEUtil.EJB_LOCAL_OBJECT) || k + .equals(J2EEUtil.EJB_OBJECT)); + } + } + + /* + * (non-Javadoc) + * + * @see com.ibm.wala.ipa.callgraph.MethodTargetSelector#mightReturnSyntheticMethod(com.ibm.wala.ipa.callgraph.CGNode, + * com.ibm.wala.classLoader.CallSiteReference) + */ + public boolean mightReturnSyntheticMethod(CGNode caller, CallSiteReference site) { + // TODO optimize this! + return true; + } + + /* + * (non-Javadoc) + * + * @see com.ibm.wala.ipa.callgraph.MethodTargetSelector#mightReturnSyntheticMethod(com.ibm.wala.types.MethodReference) + */ + public boolean mightReturnSyntheticMethod(MethodReference declaredTarget) { + // TODO optimize this! + return true; + } +} diff --git a/com.ibm.wala.j2ee/src/com/ibm/wala/j2ee/J2EEUtil.java b/com.ibm.wala.j2ee/src/com/ibm/wala/j2ee/J2EEUtil.java new file mode 100644 index 000000000..9febc5f8e --- /dev/null +++ b/com.ibm.wala.j2ee/src/com/ibm/wala/j2ee/J2EEUtil.java @@ -0,0 +1,229 @@ +/******************************************************************************* + * 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.j2ee; + +import java.util.Collection; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Set; + +import org.eclipse.jem.java.JavaParameter; +import org.eclipse.jem.java.Method; +import org.eclipse.jst.j2ee.commonarchivecore.internal.Archive; +import org.eclipse.jst.j2ee.commonarchivecore.internal.CommonarchiveFactory; +import org.eclipse.jst.j2ee.commonarchivecore.internal.exception.OpenFailureException; +import org.eclipse.jst.j2ee.commonarchivecore.internal.impl.CommonarchiveFactoryImpl; +import org.eclipse.jst.j2ee.ejb.EnterpriseBean; + +import com.ibm.wala.classLoader.ClassFileModule; +import com.ibm.wala.classLoader.JarFileModule; +import com.ibm.wala.classLoader.Module; +import com.ibm.wala.ipa.callgraph.CGNode; +import com.ibm.wala.ipa.callgraph.CallGraph; +import com.ibm.wala.j2ee.util.TopLevelArchiveModule; +import com.ibm.wala.types.ClassLoaderReference; +import com.ibm.wala.types.Descriptor; +import com.ibm.wala.types.MethodReference; +import com.ibm.wala.types.TypeName; +import com.ibm.wala.types.TypeReference; +import com.ibm.wala.util.Atom; +import com.ibm.wala.util.StringStuff; +import com.ibm.wala.util.collections.HashSetFactory; +import com.ibm.wala.util.debug.Assertions; + +/** + * + * Miscellaneous utilities for J2EE processing + * + * @author sfink + */ +public class J2EEUtil { + + public static final TypeReference EJB_HOME = + TypeReference.findOrCreateClass(ClassLoaderReference.Extension, "javax/ejb", "EJBHome"); + public static final TypeReference EJB_LOCAL_HOME = + TypeReference.findOrCreateClass(ClassLoaderReference.Extension, "javax/ejb", "EJBLocalHome"); + public static final TypeReference EJB_OBJECT = + TypeReference.findOrCreateClass(ClassLoaderReference.Extension, "javax/ejb", "EJBObject"); + public static final TypeReference EJB_LOCAL_OBJECT = + TypeReference.findOrCreateClass(ClassLoaderReference.Extension, "javax/ejb", "EJBLocalObject"); + /** + * Get the WCCM archive representing a particular module + * @param M the module to analyze + * @return Archive, or null if no WCCM conversion is possible + */ + @SuppressWarnings("restriction") + public static Archive getArchive(Module M) { + CommonarchiveFactory factory = CommonarchiveFactoryImpl.getActiveFactory(); + try { + if (M instanceof JarFileModule) { + String fileName = ((JarFileModule) M).getAbsolutePath(); + return factory.openArchive(fileName); + } else if (M instanceof TopLevelArchiveModule) { + TopLevelArchiveModule AM = (TopLevelArchiveModule) M; + return AM.materializeArchive(); + } else if (M instanceof ClassFileModule) { + return null; + } else { + Assertions.UNREACHABLE("Unprepared for module of type " + M.getClass()); + return null; + } + + } catch (OpenFailureException e) { + e.printStackTrace(); + Assertions.UNREACHABLE(); + return null; + } + } + + /** + * Create a ClassReference to represent an EnterpriseBean + * @param b the bean in question + * @param loader reference to the class loader that loads the bean + * @return ClassReference + */ + public static TypeReference ejb2TypeReference(EnterpriseBean b, ClassLoaderReference loader) { + String klass = b.getEjbClass().getQualifiedNameForReflection(); + klass = StringStuff.deployment2CanonicalTypeString(klass); + TypeReference c = TypeReference.findOrCreate(loader, TypeName.string2TypeName(klass)); + return c; + } + /** + * Create a method reference from a finder + * @param method etools method representation + * @return MethodReference that represents the method. + */ + public static MethodReference createMethodReference(Method method, ClassLoaderReference loader) { + + String tString = method.getJavaClass().getQualifiedName(); + tString = StringStuff.deployment2CanonicalTypeString(tString); + TypeReference T = TypeReference.findOrCreate(loader, TypeName.string2TypeName(tString)); + String sig = J2EEUtil.buildDescriptor(method); + Descriptor D = Descriptor.findOrCreateUTF8(sig); + Atom name = Atom.findOrCreateUnicodeAtom(method.getName()); + MethodReference ref = MethodReference.findOrCreate(T, name, D); + return ref; + } + + /** + * @param loader a governing class loader refernce + * @param iName name of an interface + * @return corresponding TypeReference + */ + public static TypeReference getTypeForInterface(ClassLoaderReference loader, String iName) { + if (Assertions.verifyAssertions) { + Assertions._assert(iName != null); + } + iName = "L" + iName.replace('.', '/'); + TypeReference iFace = TypeReference.findOrCreate(loader, TypeName.string2TypeName(iName)); + return iFace; + } + /** + * Build up a string representing the method's signature. + * Returns a string describing this Method. The string is formatted as the method name, + * followed by a parenthesized, comma-separated list of the method's formal parameter types, followed by + * the return type. + * + * This implementation clone-and-owned from com.ibm.etools.java.impl.MethodImpl.getSignature() + * + * TODO: Move me elsewhere. + * + * For example: + * + * (Ljava/lang/Object;)Z + * + * @param method the Method in question + * @return String a String representation of the signature. + */ + @SuppressWarnings("unchecked") + public static String buildDescriptor(Method method) { + + StringBuffer sb = new StringBuffer(); + + sb.append("("); + List params = method.getParameters(); + int parmSize = params.size(); + for (int j = 0; j < parmSize; j++) { + JavaParameter param = (JavaParameter) params.get(j); + if (param.isReturn()) + continue; // listParameters() includes return type in array + String s = param.getJavaType().getQualifiedName(); + sb.append(StringStuff.deployment2CanonicalDescriptorTypeString(s)); + } + sb.append(")"); + + if (method.getReturnType() == null) { + // SJF: I don't understand why this should ever happen. + // TODO: look into this + // for now, just assume void + sb.append("V"); + } else { + String r = method.getReturnType().getQualifiedName(); + sb.append(StringStuff.deployment2CanonicalDescriptorTypeString(r)); + } + + return sb.toString(); + } + + /** + * We define the "logical entrypoints" for J2EE to be the normal call graph + * entrypoints; except for servlet entrypoints ... which are treated a little + * specially. + * + * @param cg governing call graph + * @return Set of nodes which should be considered "entrypoints" for this analysis. + */ + public static Set getLogicalEntrypointNodes(CallGraph cg) { + HashSet result = HashSetFactory.make(); + for (Iterator it = cg.getEntrypointNodes().iterator(); it.hasNext();) { + CGNode n = (CGNode) it.next(); + MethodReference m = n.getMethod().getReference(); + TypeReference t = m.getDeclaringClass(); + if (isServletFrameworkType(t)) { + Set set = HashSetFactory.make(); + result.addAll(servletFrontier(cg, n, set)); + } else { + result.add(n); + } + } + return result; + } + + private static boolean isServletFrameworkType(TypeReference t) { + return t.equals(ServletEntrypoints.Servlet) + || t.equals(ServletEntrypoints.HttpServlet) + || t.equals(ServletEntrypoints.HttpJspBase); + } + + /** + * @param n a call graph node declared on javax.servlet.Servlet or + * javax.servlet.HttpServlet + * @return the set of nodes S s.t. for m in S, m is reachable from n, m is not + * a method on Servlet or HttpServlet, and there is a predecessor p of m s.t. + * p is a method on Servlet or HttpServlet. + */ + public static Collection servletFrontier(CallGraph cg, CGNode n, Set seen) { + HashSet result = HashSetFactory.make(); + seen.add(n); + for (Iterator it = cg.getSuccNodes(n); it.hasNext();) { + CGNode m = (CGNode) it.next(); + TypeReference t = m.getMethod().getDeclaringClass().getReference(); + if (isServletFrameworkType(t)) { + if (!seen.contains(m)) + result.addAll(servletFrontier(cg, m, seen)); + } else { + result.add(m); + } + } + return result; + } +} diff --git a/com.ibm.wala.j2ee/src/com/ibm/wala/j2ee/LoadFailure.java b/com.ibm.wala.j2ee/src/com/ibm/wala/j2ee/LoadFailure.java new file mode 100644 index 000000000..a09c17c1f --- /dev/null +++ b/com.ibm.wala.j2ee/src/com/ibm/wala/j2ee/LoadFailure.java @@ -0,0 +1,34 @@ +/******************************************************************************* + * 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.j2ee; + +import com.ibm.wala.util.warnings.Warning; + +/** + * + * A warning for when we can't load some reference + * + * @author sfink + */ +public class LoadFailure extends Warning { + + final Object ref; + LoadFailure(Object ref) { + super(Warning.SEVERE); + this.ref = ref; + } + public String getMsg() { + return getClass().toString() + " : " + ref; + } + public static LoadFailure create(Object ref) { + return new LoadFailure(ref); + } +} \ No newline at end of file diff --git a/com.ibm.wala.j2ee/src/com/ibm/wala/j2ee/MDBEntrypoint.java b/com.ibm.wala.j2ee/src/com/ibm/wala/j2ee/MDBEntrypoint.java new file mode 100644 index 000000000..8e033cf2e --- /dev/null +++ b/com.ibm.wala.j2ee/src/com/ibm/wala/j2ee/MDBEntrypoint.java @@ -0,0 +1,37 @@ +/******************************************************************************* + * 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.j2ee; + +import com.ibm.wala.classLoader.IMethod; +import com.ibm.wala.ipa.cha.ClassHierarchy; +import com.ibm.wala.types.TypeReference; +import com.ibm.wala.util.debug.Assertions; + +class MDBEntrypoint extends EJBLifecycleEntrypoint { + + MDBEntrypoint(IMethod m, ClassHierarchy cha, TypeReference bean) { + super(m, cha, bean); + if (Assertions.verifyAssertions) { + Assertions._assert(m.getDescriptor().equals(EJBConstants.onMessageDesc)); + } + } + + /* (non-Javadoc) + * @see com.ibm.wala.ipa.callgraph.Entrypoint#getParameterTypes(int) + */ + public TypeReference[] getParameterTypes(int i) { + if (i == 1) { + return (TypeReference[]) EJBConstants.KnownMessages.clone(); + } else { + return super.getParameterTypes(i); + } + } +} diff --git a/com.ibm.wala.j2ee/src/com/ibm/wala/j2ee/ServletEntrypoints.java b/com.ibm.wala.j2ee/src/com/ibm/wala/j2ee/ServletEntrypoints.java new file mode 100644 index 000000000..c16f41ef8 --- /dev/null +++ b/com.ibm.wala.j2ee/src/com/ibm/wala/j2ee/ServletEntrypoints.java @@ -0,0 +1,248 @@ +package com.ibm.wala.j2ee; + +/******************************************************************************* + * 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 + *******************************************************************************/ +import java.util.HashMap; +import java.util.Iterator; +import java.util.Set; + +import com.ibm.wala.classLoader.IClass; +import com.ibm.wala.classLoader.IClassLoader; +import com.ibm.wala.classLoader.IMethod; +import com.ibm.wala.ipa.callgraph.Entrypoint; +import com.ibm.wala.ipa.callgraph.Entrypoints; +import com.ibm.wala.ipa.callgraph.impl.DefaultEntrypoint; +import com.ibm.wala.ipa.cha.ClassHierarchy; +import com.ibm.wala.types.ClassLoaderReference; +import com.ibm.wala.types.Descriptor; +import com.ibm.wala.types.MethodReference; +import com.ibm.wala.types.TypeName; +import com.ibm.wala.types.TypeReference; +import com.ibm.wala.util.Atom; +import com.ibm.wala.util.ImmutableByteArray; +import com.ibm.wala.util.UTF8Convert; +import com.ibm.wala.util.collections.HashMapFactory; +import com.ibm.wala.util.collections.HashSetFactory; +import com.ibm.wala.util.debug.Assertions; +import com.ibm.wala.util.debug.Trace; + +/** + * + * This class provides an iterator of entrypoints that are implementations of + * servlet methods. + * + * @author sfink + */ +public class ServletEntrypoints implements Entrypoints, EJBConstants { + + static final boolean DEBUG = false; + + private final static Atom destroyName = Atom.findOrCreateUnicodeAtom("destroy"); + private final static Descriptor destroyDesc = Descriptor.findOrCreateUTF8("()V"); + + private final static Atom getServletConfigName = Atom.findOrCreateUnicodeAtom("getServletConfig"); + private final static Descriptor getServletConfigDesc = Descriptor.findOrCreateUTF8("()Ljavax/servlet/ServletConfig;"); + + private final static Atom getServletInfoName = Atom.findOrCreateUnicodeAtom("getServletInfo"); + private final static Descriptor getServletInfoDesc = Descriptor.findOrCreateUTF8("()Ljava/lang/String;"); + + private final static Atom initName = Atom.findOrCreateUnicodeAtom("init"); + private final static Descriptor initDesc = Descriptor.findOrCreateUTF8("(Ljavax/servlet/ServletConfig;)V"); + + public final static Atom serviceName = Atom.findOrCreateUnicodeAtom("service"); + private final static byte[] serviceDescAtom = UTF8Convert + .toUTF8("(Ljavax/servlet/ServletRequest;Ljavax/servlet/ServletResponse;)V"); + private final static Descriptor serviceDesc = Descriptor.findOrCreate(new ImmutableByteArray(serviceDescAtom)); + + public final static Atom finalizeName = Atom.findOrCreateUnicodeAtom("finalize"); + private final static Descriptor finalizeDesc = Descriptor.findOrCreateUTF8("()V"); + + private final static Atom[] servletMethodNames = { destroyName, getServletConfigName, getServletInfoName, initName, serviceName, + finalizeName }; + + private final static Descriptor[] servletMethodDescs = { destroyDesc, getServletConfigDesc, getServletInfoDesc, initDesc, + serviceDesc, finalizeDesc }; + + private final static TypeName servletName = TypeName.string2TypeName("Ljavax/servlet/Servlet"); + public final static TypeReference Servlet = TypeReference.findOrCreate(ClassLoaderReference.Extension, servletName); + + private final static TypeName httpServletName = TypeName.string2TypeName("Ljavax/servlet/http/HttpServlet"); + public final static TypeReference HttpServlet = TypeReference.findOrCreate(ClassLoaderReference.Extension, httpServletName); + + private final static TypeName httpJspBaseName = TypeName.string2TypeName("Lcom/ibm/ws/webcontainer/jsp/runtime/HttpJspBase"); + public final static TypeReference HttpJspBase = TypeReference.findOrCreate(ClassLoaderReference.Extension, httpJspBaseName); + + final static TypeName servletRequest = TypeName.string2TypeName("Ljavax/servlet/ServletRequest"); + public final static TypeReference ServletRequest = TypeReference.findOrCreate(ClassLoaderReference.Extension, servletRequest); + + public final static TypeName servletResponse = TypeName.string2TypeName("Ljavax/servlet/ServletResponse"); + public final static TypeReference ServletResponse = TypeReference.findOrCreate(ClassLoaderReference.Extension, servletResponse); + + final static TypeName httpServletRequest = TypeName.string2TypeName("Ljavax/servlet/http/HttpServletRequest"); + public final static TypeReference HttpServletRequest = TypeReference.findOrCreate(ClassLoaderReference.Extension, servletRequest); + + public final static TypeName httpServletResponse = TypeName.string2TypeName("Ljavax/servlet/http/HttpServletResponse"); + public final static TypeReference HttpServletResponse = TypeReference.findOrCreate(ClassLoaderReference.Extension, + servletResponse); + + private final static TypeName servletContext = TypeName.string2TypeName("Ljavax/servlet/ServletContext"); + public final static TypeReference ServletContext = TypeReference.findOrCreate(ClassLoaderReference.Extension, servletContext); + + private final static TypeName servletConfig = TypeName.string2TypeName("Ljavax/servlet/ServletConfig"); + public final static TypeReference ServletConfig = TypeReference.findOrCreate(ClassLoaderReference.Extension, servletConfig); + + private final static TypeName walaHttpServletRequest = TypeName + .string2TypeName("Lcom/ibm/wala/model/javax/servlet/http/HttpServletRequest"); + public final static TypeReference WalaHttpServletRequest = TypeReference.findOrCreate(ClassLoaderReference.Extension, + walaHttpServletRequest); + + private final static TypeName walaHttpServletResponse = TypeName + .string2TypeName("Lcom/ibm/wala/model/javax/servlet/http/HttpServletResponse"); + public final static TypeReference WalaHttpServletResponse = TypeReference.findOrCreate(ClassLoaderReference.Extension, + walaHttpServletResponse); + + private final static TypeName walaServletContextModel = TypeName + .string2TypeName("Lcom/ibm/wala/model/javax/servlet/ServletContext"); + public final static TypeReference WalaServletContextModel = TypeReference.findOrCreate(ClassLoaderReference.Extension, + walaServletContextModel); + + private final static TypeName walaServletConfigModel = TypeName + .string2TypeName("Lcom/ibm/wala/model/javax/servlet/ServletConfig"); + public final static TypeReference WalaServletConfigModel = TypeReference.findOrCreate(ClassLoaderReference.Extension, + walaServletConfigModel); + + private final static TypeName actionServlet = TypeName.string2TypeName("Lorg/apache/struts/action/ActionServlet"); + + public final static MethodReference servletInit = MethodReference.findOrCreate(Servlet,initName,initDesc); + + /** + * Set of Entrypoint + */ + private Set entrypoints = HashSetFactory.make(); + + /** + * Set of servlet implementations found. + */ + private Set servlets = HashSetFactory.make(); + + /** + * Mapping of TypeName -> TypeReference; this map controls selection of + * concrete types for parameters to some servlet methods. + */ + private final static HashMap concreteParameterMap = HashMapFactory.make(5); + static { + concreteParameterMap.put(httpServletRequest, WalaHttpServletRequest); + concreteParameterMap.put(httpServletResponse, WalaHttpServletResponse); + concreteParameterMap.put(servletRequest, WalaHttpServletRequest); + concreteParameterMap.put(servletResponse, WalaHttpServletResponse); + concreteParameterMap.put(servletContext, WalaServletContextModel); + concreteParameterMap.put(servletConfig, WalaServletConfigModel); + } + + /** + * Constructor. + * @param scope + * scope of analysis + * @param cha + * loaded class hierarchy + */ + public ServletEntrypoints(J2EEAnalysisScope scope, ClassHierarchy cha) { + + TypeReference servletType = TypeReference.findOrCreate(scope.getExtensionLoader(), servletName); + TypeReference actionServletType = TypeReference.findOrCreate(scope.getApplicationLoader(), actionServlet); + IClass actionServletClass = cha.lookupClass(actionServletType); + + ClassLoaderReference appLoaderRef = scope.getApplicationLoader(); + IClassLoader appLoader = cha.getLoader(appLoaderRef); + + for (Iterator it = appLoader.iterateAllClasses(); it.hasNext();) { + IClass klass = (IClass) it.next(); + if (DEBUG) { + Trace.println(getClass() + " consider " + klass); + } + if (cha.lookupClass(klass.getReference()) == null) { + continue; + } + // ignore struts ActionServlets + if (cha.lookupClass(actionServletType) != null) { + if (cha.isSubclassOf(klass, actionServletClass)) { + continue; + } + } + if (cha.implementsInterface(klass, servletType)) { + servlets.add(klass); + final TypeReference type = klass.getReference(); + + for (int i = 0; i < servletMethodNames.length; i++) { + Atom name = servletMethodNames[i]; + Descriptor desc = servletMethodDescs[i]; + MethodReference M = MethodReference.findOrCreate(type, name, desc); + IMethod m = cha.resolveMethod(M); + if (cha.resolveMethod(M) != null) { + entrypoints.add(new DefaultEntrypoint(m, cha) { + + /** + * Assume all ServletRequest and ServletResponse are HTTP flavor. + */ + public TypeReference[] getParameterTypes(int i) { + if (i == 0) { + // "this" pointer + return new TypeReference[] { type }; + } else { + TypeReference[] tArray = super.getParameterTypes(i); + if (Assertions.verifyAssertions) { + Assertions._assert(tArray.length == 1); + } + TypeReference T = tArray[0]; + TypeName n = T.getName(); + TypeReference Tp = concreteParameterMap.get(n); + if (Tp != null) { + T = Tp; + } + return new TypeReference[] { T }; + } + } + }); + } + } + } + } + } + + /* + * (non-Javadoc) + * + * @see com.ibm.detox.ipa.callgraph.Entrypoints#iterator() + */ + public Iterator iterator() { + return entrypoints.iterator(); + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#toString() + */ + public String toString() { + StringBuffer result = new StringBuffer(); + result.append("Servlets:"); + Iterator it = servlets.iterator(); + if (it.hasNext()) { + while (it.hasNext()) { + result.append("\n "); + result.append(it.next()); + } + } else { + result.append(" none"); + } + return result.toString(); + } +} diff --git a/com.ibm.wala.j2ee/src/com/ibm/wala/j2ee/StrutsEntrypoints.java b/com.ibm.wala.j2ee/src/com/ibm/wala/j2ee/StrutsEntrypoints.java new file mode 100644 index 000000000..90f6fe5cc --- /dev/null +++ b/com.ibm.wala.j2ee/src/com/ibm/wala/j2ee/StrutsEntrypoints.java @@ -0,0 +1,229 @@ +/******************************************************************************* + * 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.j2ee; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; + +import com.ibm.wala.classLoader.IClass; +import com.ibm.wala.classLoader.IClassLoader; +import com.ibm.wala.classLoader.IMethod; +import com.ibm.wala.ipa.callgraph.Entrypoint; +import com.ibm.wala.ipa.callgraph.Entrypoints; +import com.ibm.wala.ipa.callgraph.impl.DefaultEntrypoint; +import com.ibm.wala.ipa.cha.ClassHierarchy; +import com.ibm.wala.ipa.cha.ClassHierarchyException; +import com.ibm.wala.types.ClassLoaderReference; +import com.ibm.wala.types.Descriptor; +import com.ibm.wala.types.MethodReference; +import com.ibm.wala.types.TypeName; +import com.ibm.wala.types.TypeReference; +import com.ibm.wala.util.Atom; +import com.ibm.wala.util.collections.HashMapFactory; +import com.ibm.wala.util.collections.HashSetFactory; +import com.ibm.wala.util.debug.Assertions; + +/** + * + * This class provides an iterator of entrypoints that are implementations of + * org.apache.struts.action.Action + * + * @author sfink + */ +public class StrutsEntrypoints implements Entrypoints, EJBConstants { + + public final static Atom executeName = Atom.findOrCreateUnicodeAtom("execute"); + + /** + * Should we attempt to speculate that methods are dispatched to based on the + * method descriptor? + */ + public final static boolean SPECULATE_DISPATCH_ACTIONS = true; + + private final static String executeDescString = "(Lorg/apache/struts/action/ActionMapping;Lorg/apache/struts/action/ActionForm;Ljavax/servlet/ServletRequest;Ljavax/servlet/ServletResponse;)Lorg/apache/struts/action/ActionForward;"; + private final static String httpExecuteDescString = "(Lorg/apache/struts/action/ActionMapping;Lorg/apache/struts/action/ActionForm;Ljavax/servlet/http/HttpServletRequest;Ljavax/servlet/http/HttpServletResponse;)Lorg/apache/struts/action/ActionForward;"; + + private final static Descriptor executeDesc = Descriptor.findOrCreateUTF8(executeDescString); + private final static Descriptor httpExecuteDesc = Descriptor.findOrCreateUTF8(httpExecuteDescString); + + private final static TypeName actionName = TypeName.string2TypeName("Lorg/apache/struts/action/Action"); + + /** + * Map: MethodReference -> Entrypoint + */ + private Map entrypoints = HashMapFactory.make(); + + /** + * Set of action implementations found. + */ + private Set actions = HashSetFactory.make(); + + /** + * Mapping of TypeName -> TypeReference; this map controls selection of + * concrete types for parameters to some servlet methods. + */ + private final static HashMap concreteParameterMap = HashMapFactory.make(2); + static { + concreteParameterMap.put(ServletEntrypoints.httpServletRequest, ServletEntrypoints.WalaHttpServletRequest); + concreteParameterMap.put(ServletEntrypoints.httpServletResponse, ServletEntrypoints.WalaHttpServletResponse); + concreteParameterMap.put(ServletEntrypoints.servletRequest, ServletEntrypoints.WalaHttpServletRequest); + concreteParameterMap.put(ServletEntrypoints.servletResponse, ServletEntrypoints.WalaHttpServletResponse); + } + + /** + * Constructor. + * + * @param scope + * scope of analysis + * @param cha + * loaded class hierarchy + */ + public StrutsEntrypoints(J2EEAnalysisScope scope, ClassHierarchy cha) { + + TypeReference actionType = TypeReference.findOrCreate(scope.getApplicationLoader(), actionName); + IClass actionClass = cha.lookupClass(actionType); + + if (actionClass == null) { + return; + } + + ClassLoaderReference appLoaderRef = scope.getApplicationLoader(); + IClassLoader appLoader = cha.getLoader(appLoaderRef); + + for (Iterator it = appLoader.iterateAllClasses(); it.hasNext();) { + IClass klass = (IClass) it.next(); + if (cha.lookupClass(klass.getReference()) == null) { + continue; + } + if (klass.isAbstract()) { + continue; + } + if (klass.getReference().equals(actionType)) { + continue; + } + if (cha.isSubclassOf(klass, actionClass)) { + actions.add(klass); + TypeReference type = klass.getReference(); + MethodReference M = MethodReference.findOrCreate(type, executeName, httpExecuteDesc); + + IMethod im = cha.resolveMethod(M); + if (im != null) { + entrypoints.put(M, new StrutsActionEntrypoint(klass, im, cha)); + } + + if (SPECULATE_DISPATCH_ACTIONS) { + addSpeculativeDispatchMethods(klass, cha); + } + } + } + } + + /** + * Add any methods that look like they might be DispatchAction targets, based + * on the method signature. + * + * TODO: instead, parse the struts xml directly. + * @param klass + * an Action + */ + private void addSpeculativeDispatchMethods(IClass klass, ClassHierarchy cha) { + IClass C = klass; + while (C != null) { + for (Iterator it = C.getDeclaredMethods(); it.hasNext();) { + IMethod M = (IMethod) it.next(); + Descriptor D = M.getDescriptor(); + if (D.equals(executeDesc) || D.equals(httpExecuteDesc)) { + MethodReference m = MethodReference.findOrCreate(klass.getReference(), M.getName(), M.getDescriptor()); + entrypoints.put(m, new StrutsActionEntrypoint(C, M, cha)); + } + } + try { + C = C.getSuperclass(); + } catch (ClassHierarchyException e) { + e.printStackTrace(); + Assertions.UNREACHABLE(); + } + } + } + + /* + * (non-Javadoc) + * + * @see com.ibm.detox.ipa.callgraph.Entrypoints#iterator() + */ + public Iterator iterator() { + return entrypoints.values().iterator(); + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#toString() + */ + public String toString() { + StringBuffer result = new StringBuffer(); + result.append("Actions:"); + Iterator it = actions.iterator(); + if (it.hasNext()) { + while (it.hasNext()) { + result.append("\n "); + result.append(it.next()); + } + } else { + result.append(" none"); + } + return result.toString(); + } + + /** + * @param m + * @return true iff m is an entrypoint recorded by this class + */ + public boolean contains(MethodReference m) { + return entrypoints.keySet().contains(m); + } + + /** + * + * @author sfink + * + * An entrypoint which assumes all ServletRequest and ServletResponses are of + * the HTTP flavor. + */ + private static class StrutsActionEntrypoint extends DefaultEntrypoint { + private final TypeReference receiver; + + public StrutsActionEntrypoint(IClass concreteType, IMethod method, ClassHierarchy cha) { + super(method, cha); + receiver = concreteType.getReference(); + } + + public TypeReference[] getParameterTypes(int i) { + if (i == 0) { + return new TypeReference[] { receiver }; + } else { + TypeReference[] tarray = super.getParameterTypes(i); + if (Assertions.verifyAssertions) { + Assertions._assert(tarray.length == 1); + } + TypeReference T = tarray[0]; + TypeName n = T.getName(); + TypeReference Tprime = concreteParameterMap.get(n); + if (Tprime != null) { + T = Tprime; + } + return new TypeReference[] { T }; + } + } + } +} diff --git a/com.ibm.wala.j2ee/src/com/ibm/wala/j2ee/SummarizedEJBMethod.java b/com.ibm.wala.j2ee/src/com/ibm/wala/j2ee/SummarizedEJBMethod.java new file mode 100644 index 000000000..16a26b633 --- /dev/null +++ b/com.ibm.wala.j2ee/src/com/ibm/wala/j2ee/SummarizedEJBMethod.java @@ -0,0 +1,34 @@ +/******************************************************************************* + * 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.j2ee; + +import com.ibm.wala.classLoader.IClass; +import com.ibm.wala.ipa.summaries.MethodSummary; +import com.ibm.wala.ipa.summaries.SummarizedMethod; +import com.ibm.wala.types.MethodReference; + +/** + * @author sfink + */ +public class SummarizedEJBMethod extends SummarizedMethod { + + private final BeanMetaData bean; + + public SummarizedEJBMethod(BeanMetaData bean, MethodReference ref, MethodSummary summary, IClass declaringClass) { + super(ref, summary, declaringClass); + this.bean = bean; + } + + public BeanMetaData getBean() { + return bean; + } + +} diff --git a/com.ibm.wala.j2ee/src/com/ibm/wala/j2ee/TransactionUtil.java b/com.ibm.wala.j2ee/src/com/ibm/wala/j2ee/TransactionUtil.java new file mode 100644 index 000000000..b6d18c32c --- /dev/null +++ b/com.ibm.wala.j2ee/src/com/ibm/wala/j2ee/TransactionUtil.java @@ -0,0 +1,143 @@ +// Licensed Materials - Property of IBM +// 5724-D15 +// (C) Copyright IBM Corporation 2004. All Rights Reserved. +// Note to U.S. Government Users Restricted Rights: Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp. +// +// --------------------------------------------------------------------------- + + +package com.ibm.wala.j2ee; + +import java.util.Collections; +import java.util.Iterator; +import java.util.Set; +import java.util.TreeSet; + +import org.eclipse.jem.java.Method; +import org.eclipse.jst.j2ee.commonarchivecore.internal.Archive; +import org.eclipse.jst.j2ee.commonarchivecore.internal.EARFile; +import org.eclipse.jst.j2ee.commonarchivecore.internal.EJBJarFile; +import org.eclipse.jst.j2ee.ejb.AssemblyDescriptor; +import org.eclipse.jst.j2ee.ejb.EJBJar; +import org.eclipse.jst.j2ee.ejb.EnterpriseBean; +import org.eclipse.jst.j2ee.ejb.MethodElement; +import org.eclipse.jst.j2ee.ejb.MethodElementKind; +import org.eclipse.jst.j2ee.ejb.MethodTransaction; + +import com.ibm.wala.types.ClassLoaderReference; +import com.ibm.wala.util.collections.HashSetFactory; +import com.ibm.wala.util.debug.Trace; + +/** + * + * Utilities for dealing with transaction declarations. + * + * @author sfink + */ +public class TransactionUtil { + + private static final boolean DEBUG = false; + + private final static String EJBHOME = "javax.ejb.EJBHome"; + private final static String EJBLOCALHOME = "javax.ejb.EJBLocalHome"; + private final static String EJBOBJECT = "javax.ejb.EJBObject"; + private final static String EJBLOCALOBJECT = "javax.ejb.EJBLocalObject"; + + /** + * Create a set of objects to represent transaction entrypoints + * defined in this module. + */ + @SuppressWarnings({ "restriction", "unchecked" }) + public static Set createDeclaredTransactionEntries(Archive A, ClassLoaderReference loader) { + + if (DEBUG) { + Trace.println("createDeclaredTransactionEntries: " + A + " type " + A.getClass()); + } + + if (A.isEJBJarFile()) { + // extract the deployment descriptor + EJBJar DD = ((EJBJarFile) A).getDeploymentDescriptor(); + return createDeclaredTransactionEntries(DD, loader); + } else if (A.isEARFile()) { + EARFile ear = (EARFile) A; + Set result = HashSetFactory.make(); + for (Iterator it = ear.getEJBJarFiles().iterator(); it.hasNext();) { + EJBJarFile j = (EJBJarFile) it.next(); + result.addAll(createDeclaredTransactionEntries(j, loader)); + } + return result; + } else { + return Collections.emptySet(); + } + } + + /** + * Create a set of objects to represent transaction entrypoints + * defined in this module. + */ + @SuppressWarnings("unchecked") + private static Set createDeclaredTransactionEntries(EJBJar DD, ClassLoaderReference loader) { + + if (DEBUG) { + Trace.println("createDeclaredTransactionEntries: " + DD); + } + + TreeSet result = new TreeSet(); + AssemblyDescriptor AD = DD.getAssemblyDescriptor(); + if (AD == null) { + System.err.println("Warning: no assembly descriptor found for EJBJar: " + DD); + return Collections.emptySet(); + } + for (Iterator it = AD.getMethodTransactions().iterator(); it.hasNext();) { + MethodTransaction T = (MethodTransaction) it.next(); + if (DEBUG) { + Trace.println("got MethodTransaction " + T); + } + int TType = T.getTransactionAttribute().getValue(); + for (Iterator elements = T.getMethodElements().iterator(); elements.hasNext();) { + MethodElement M = (MethodElement) elements.next(); + EnterpriseBean b = M.getEnterpriseBean(); + int elementKind = M.getType().getValue(); + Method[] methods = M.getMethods(); + for (int i = 0; i < methods.length; i++) { + int kind = (elementKind == MethodElementKind.UNSPECIFIED) ? deduceKind(b, methods[i]) : elementKind; + if (kind != MethodElementKind.UNSPECIFIED) { + result.add(new DeploymentDeclaredTransaction(b, methods[i], M, loader, kind, TType)); + } + } + } + } + return result; + } + + /** + * Figure out the EJB interface to which a method belongs + */ + private static int deduceKind(EnterpriseBean b, Method method) { + String home = b.getHomeInterfaceName(); + String localHome = b.getLocalHomeInterfaceName(); + String local = b.getLocalInterfaceName(); + String remote = b.getRemoteInterfaceName(); + String name = method.getJavaClass().getJavaName(); + + if (DEBUG) { + Trace.println("deduceKind: " + b + " " + name); + } + + if (name.equals(home) || name.equals(EJBHOME)) { + return MethodElementKind.HOME; + } else if (name.equals(localHome) || name.equals(EJBLOCALHOME)) { + return MethodElementKind.LOCAL_HOME; + } else if (name.equals(local) || name.equals(EJBLOCALOBJECT)) { + return MethodElementKind.LOCAL; + } else if (name.equals(remote) || name.equals(EJBOBJECT)) { + return MethodElementKind.REMOTE; + } else if (b.isMessageDriven() && method.getName().equals("onMessage")) { + // treat message-driven transactions like remote ones + return MethodElementKind.REMOTE; + } else { + // some other type we don't handle; give up. + return MethodElementKind.UNSPECIFIED; + } + } +} diff --git a/com.ibm.wala.j2ee/src/com/ibm/wala/j2ee/client/AnalysisEngine.java b/com.ibm.wala.j2ee/src/com/ibm/wala/j2ee/client/AnalysisEngine.java new file mode 100644 index 000000000..3cfbb214b --- /dev/null +++ b/com.ibm.wala.j2ee/src/com/ibm/wala/j2ee/client/AnalysisEngine.java @@ -0,0 +1,44 @@ +/******************************************************************************* + * 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.j2ee.client; + +import java.util.jar.JarFile; + +import com.ibm.wala.classLoader.Module; + +/** + * + * An AnalysisEngine analyzes one or more J2EE modules, including + * ear files, J2EE clients, web modules, and ejb modules. + * + * @author Logan Colby + * @author Stephen Fink + */ + +public interface AnalysisEngine extends com.ibm.wala.client.AnalysisEngine { + + /** + * Specify the jar file that represent the contents of the j2ee.jar + * that the application relies on + * + * @param libs an array of jar files; for WAS, j2ee.jar and webcontainer.jar + */ + void setJ2EELibraries(JarFile[] libs); + + /** + * Specify the mdoules that represent the contents of the j2ee.jar + * that the application relies on + * + * @param libs an array of Modules; for WAS, j2ee.jar and webcontainer.jar + */ + void setJ2EELibraries(Module[] libs); + +} diff --git a/com.ibm.wala.j2ee/src/com/ibm/wala/j2ee/client/CallGraphBuilderFactory.java b/com.ibm.wala.j2ee/src/com/ibm/wala/j2ee/client/CallGraphBuilderFactory.java new file mode 100644 index 000000000..4619b45ca --- /dev/null +++ b/com.ibm.wala.j2ee/src/com/ibm/wala/j2ee/client/CallGraphBuilderFactory.java @@ -0,0 +1,63 @@ +/******************************************************************************* + * 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.j2ee.client; + +import com.ibm.wala.ipa.callgraph.AnalysisOptions; +import com.ibm.wala.ipa.callgraph.CallGraphBuilder; +import com.ibm.wala.ipa.cha.ClassHierarchy; +import com.ibm.wala.j2ee.DeploymentMetaData; +import com.ibm.wala.j2ee.J2EEAnalysisScope; +import com.ibm.wala.util.warnings.WarningSet; + +/** + * + * A factory for call graph builders; tailored to J2EE + * + * @author sfink + */ +public interface CallGraphBuilderFactory extends com.ibm.wala.client.CallGraphBuilderFactory { + + public final static String IMPL_PROPERTY = "callGraphBuilderFactoryImplementation"; + + public final static String RTA_BUILDER_FACTORY = "com.ibm.wala.j2ee.client.impl.RTABuilderFactory"; + + public final static String XTA_BUILDER_FACTORY = "com.ibm.wala.j2ee.client.impl.XTABuilderFactory"; + + public final static String XTA_CONTAINER_BUILDER_FACTORY = "com.ibm.wala.j2ee.client.impl.XTAContainerBuilderFactory"; + + public final static String ZERO_CFA_BUILDER_FACTORY = "com.ibm.wala.j2ee.client.impl.ZeroCFABuilderFactory"; + + public final static String ZERO_CONTAINER_CFA_BUILDER_FACTORY = "com.ibm.wala.j2ee.client.impl.ZeroContainerCFABuilderFactory"; + + public final static String ZERO_ONE_CFA_BUILDER_FACTORY = "com.ibm.wala.j2ee.client.impl.ZeroOneCFABuilderFactory"; + + public final static String ZERO_ONE_CONTAINER_CFA_BUILDER_FACTORY = "com.ibm.wala.j2ee.client.impl.ZeroOneContainerCFABuilderFactory"; + + public final static String OBJECT_SENSITIVE_CONTAINER_HACK_CFA_BUILDER_FACTORY = "com.ibm.wala.j2ee.client.impl.ObjectSensitiveContainerHackCFABuilderFactory"; + + /** + * @param options + * options that govern call graph construction + * @param cha + * governing class hierarchy + * @param scope + * representation of the analysis scope + * @param dmd + * deployment descriptor abstraction + * @param warnings + * an object which tracks analysis warnings + * @param keepPointsTo + * preserve PointsTo graph for posterity? + * + */ + CallGraphBuilder make(AnalysisOptions options, ClassHierarchy cha, J2EEAnalysisScope scope, DeploymentMetaData dmd, + WarningSet warnings, boolean keepPointsTo); +} diff --git a/com.ibm.wala.j2ee/src/com/ibm/wala/j2ee/client/IArrayContents.java b/com.ibm.wala.j2ee/src/com/ibm/wala/j2ee/client/IArrayContents.java new file mode 100644 index 000000000..bfc3c6e71 --- /dev/null +++ b/com.ibm.wala.j2ee/src/com/ibm/wala/j2ee/client/IArrayContents.java @@ -0,0 +1,25 @@ +/******************************************************************************* + * 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.j2ee.client; + +/** + * + * Interface to information about an array + * + * @author sfink + */ +public interface IArrayContents { + + /** + * @return declared type of this array + */ + IClass getDeclaredClass(); +} \ No newline at end of file diff --git a/com.ibm.wala.j2ee/src/com/ibm/wala/j2ee/client/IClass.java b/com.ibm.wala.j2ee/src/com/ibm/wala/j2ee/client/IClass.java new file mode 100644 index 000000000..64b8418fb --- /dev/null +++ b/com.ibm.wala.j2ee/src/com/ibm/wala/j2ee/client/IClass.java @@ -0,0 +1,39 @@ +/******************************************************************************* + * 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.j2ee.client; + +/** + * + * Interface to information about a class. + * + * @author sfink + */ +public interface IClass { + /** + * This method returns something like "Primordial" or "Application" + * + * @return String representation of the name of the classloader + */ + public abstract String getClassLoaderName(); + /** + * This method returns something like com.ibm.foo.Foo + * + * @return String representation of the name of the method + */ + public abstract String getName(); + /** + * This method returns something like com.ibm.foo + * + * @return String representation of the name of the package + */ + public abstract String getPackage(); + +} \ No newline at end of file diff --git a/com.ibm.wala.j2ee/src/com/ibm/wala/j2ee/client/IField.java b/com.ibm.wala.j2ee/src/com/ibm/wala/j2ee/client/IField.java new file mode 100644 index 000000000..23a1fb516 --- /dev/null +++ b/com.ibm.wala.j2ee/src/com/ibm/wala/j2ee/client/IField.java @@ -0,0 +1,39 @@ +/******************************************************************************* + * 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.j2ee.client; + +/** + * + * Interface to information about a field. + * + * @author sfink + */ +public interface IField { + /** + * This method returns something of the form com.foo.bar + * + * @return String representation of the declaring class + */ + public abstract IClass getDeclaringClass(); + /** + * This method returns something like "Primordial" or "Application" + * + * @return String representation of the name of the classloader + */ + public abstract String getClassLoaderName(); + /** + * This method returns something like createLargeOrder + * + * @return String representation of the name of the method + */ + public abstract String getName(); + +} \ No newline at end of file diff --git a/com.ibm.wala.j2ee/src/com/ibm/wala/j2ee/client/IMethod.java b/com.ibm.wala.j2ee/src/com/ibm/wala/j2ee/client/IMethod.java new file mode 100644 index 000000000..798991bfa --- /dev/null +++ b/com.ibm.wala.j2ee/src/com/ibm/wala/j2ee/client/IMethod.java @@ -0,0 +1,56 @@ +/******************************************************************************* + * 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.j2ee.client; + +/** + * Interface to information about a method. + * + * @author sfink + */ +public interface IMethod { + /** + * This method returns something of the form com.foo.bar + * + * @return String representation of the declaring class + */ + public abstract IClass getDeclaringClass(); + /** + * This method returns something like "Primordial" or "Application" + * + * @return String representation of the name of the classloader + */ + public abstract String getClassLoaderName(); + /** + * This method returns something like createLargeOrder + * + * @return String representation of the name of the method + */ + public abstract String getName(); + /** + * A descriptor is a string like: + * (IILjava.lang.String;SLjava.sql.Date;)Ljava.lang.Integer; + * @return String representation of the signature + */ + public abstract String getDescriptor(); + /** + * A signature is a string like: + * com.foo.bar.createLargeOrder(IILjava/lang/String;SLjava/sql/Date;)Ljava/lang/Integer; + * @return String representation of the signature + */ + public abstract String getSignature(); + /** + * A selector is a string like: + * createLargeOrder(IILjava.lang.String;SLjava.sql.Date;)Ljava.lang.Integer; + * @return String representation of the selector + */ + public abstract String getSelector(); +} \ No newline at end of file diff --git a/com.ibm.wala.j2ee/src/com/ibm/wala/j2ee/client/IProgramLocation.java b/com.ibm.wala.j2ee/src/com/ibm/wala/j2ee/client/IProgramLocation.java new file mode 100644 index 000000000..5e745fa31 --- /dev/null +++ b/com.ibm.wala.j2ee/src/com/ibm/wala/j2ee/client/IProgramLocation.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * 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.j2ee.client; + + +/** + * + * Represents a static program location, a bytecode index in a method + * + * @author sfink + */ +public interface IProgramLocation { + + IMethod getMethod(); + + int getBytecodeIndex(); + + int getLineNumber(); +} diff --git a/com.ibm.wala.j2ee/src/com/ibm/wala/j2ee/client/PruneCallGraph.java b/com.ibm.wala.j2ee/src/com/ibm/wala/j2ee/client/PruneCallGraph.java new file mode 100644 index 000000000..e78d6914c --- /dev/null +++ b/com.ibm.wala.j2ee/src/com/ibm/wala/j2ee/client/PruneCallGraph.java @@ -0,0 +1,150 @@ +// Licensed Materials - Property of IBM +// 5724-D15 +// (C) Copyright IBM Corporation 2004. All Rights Reserved. +// Note to U.S. Government Users Restricted Rights: Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp. +// +// --------------------------------------------------------------------------- + +package com.ibm.wala.j2ee.client; + +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; + +import com.ibm.wala.dataflow.graph.AbstractMeetOperator; +import com.ibm.wala.dataflow.graph.BitVectorFramework; +import com.ibm.wala.dataflow.graph.BooleanIdentity; +import com.ibm.wala.dataflow.graph.BooleanSolver; +import com.ibm.wala.dataflow.graph.BooleanUnion; +import com.ibm.wala.dataflow.graph.DataflowSolver; +import com.ibm.wala.dataflow.graph.ITransferFunctionProvider; +import com.ibm.wala.fixedpoint.impl.UnaryOperator; +import com.ibm.wala.fixpoint.BooleanVariable; +import com.ibm.wala.fixpoint.TrueOperator; +import com.ibm.wala.ipa.callgraph.CGNode; +import com.ibm.wala.ipa.callgraph.CallGraph; +import com.ibm.wala.util.collections.Filter; +import com.ibm.wala.util.collections.HashSetFactory; +import com.ibm.wala.util.collections.Iterator2Collection; +import com.ibm.wala.util.debug.Assertions; +import com.ibm.wala.util.debug.Trace; +import com.ibm.wala.util.graph.impl.GraphInverter; +import com.ibm.wala.util.graph.traverse.DFS; +import com.ibm.wala.util.intset.MutableMapping; +import com.ibm.wala.util.intset.OrdinalSetMapping; + +/** + * + * This class will prune a call graph to include only nodes from which some + * class which matches a certain filter is reachable. + * + * For example, we can (and do) use this class to prune a call graph to include + * only nodes for which some method A is reachable where A.getDeclaringClass() + * is loaded by the application loader. This pruned call graph should hold all + * the information needed to analyze transaction boundaries. + * + * @author sfink + * + */ +public class PruneCallGraph { + + private final static boolean DEBUG = false; + + /** + * @param F + * a filter which may accept some nodes in a call graph + * @return the Set of nodes N s.t. there exists some path from the fake root + * node of G to some node M that contains N, where F accepts node M. + */ + public static Set computeNodesOnPathToAccept(CallGraph G, Filter F) { + OnPathSystem S = new OnPathSystem(G, F); + S.solve(); + Set reachable = DFS.getReachableNodes(G, Collections.singleton(G.getFakeRootNode())); + HashSet result = HashSetFactory.make(); + for (Iterator it = reachable.iterator(); it.hasNext();) { + CGNode N = it.next(); + BooleanVariable B = S.getVariable(N); + if (B.getValue()) + result.add(N); + if (DEBUG) { + Trace.println("On path " + N + " " + B.getValue()); + } + } + return result; + } + + /** + * A dataflow system which computes a boolean B(N) for every node in the call + * graph, where B(N) = true if there exists some path from the fake root node + * of G to some node M that contains N, where F accepts node M, and B(N) = + * false otherwise. + */ + private static class OnPathSystem { + + private CallGraph CG; + + private Filter filter; + + private Collection nodes; + + private DataflowSolver solver; + + /** + * @param CG + * governing call graph + */ + public OnPathSystem(CallGraph CG, Filter F) { + this.CG = CG; + this.filter = F; + this.nodes = new Iterator2Collection(CG.iterateNodes()); + } + + public BooleanVariable getVariable(CGNode n) { + return (BooleanVariable) solver.getOut(n); + } + + /* + * (non-Javadoc) + * + * @see com.ibm.wala.dataflow.fixpoint.Solvable#solve() + */ + public boolean solve() { + final OrdinalSetMapping values = new MutableMapping(nodes.toArray()); + ITransferFunctionProvider functions = new ITransferFunctionProvider() { + + public UnaryOperator getNodeTransferFunction(CGNode node) { + CGNode n = (CGNode) node; + if (filter.accepts(n)) { + return TrueOperator.instance(); + } else { + return BooleanIdentity.instance(); + } + } + + public boolean hasNodeTransferFunctions() { + return true; + } + + public UnaryOperator getEdgeTransferFunction(CGNode from, CGNode to) { + Assertions.UNREACHABLE(); + return null; + } + + public boolean hasEdgeTransferFunctions() { + return false; + } + + public AbstractMeetOperator getMeetOperator() { + return BooleanUnion.instance(); + } + + }; + + BitVectorFramework F = new BitVectorFramework(GraphInverter.invert(CG), functions, values); + solver = new BooleanSolver(F); + return solver.solve(); + } + } +} diff --git a/com.ibm.wala.j2ee/src/com/ibm/wala/j2ee/client/impl/AbstractAnalysisEngine.java b/com.ibm.wala.j2ee/src/com/ibm/wala/j2ee/client/impl/AbstractAnalysisEngine.java new file mode 100644 index 000000000..22fb2f5d2 --- /dev/null +++ b/com.ibm.wala.j2ee/src/com/ibm/wala/j2ee/client/impl/AbstractAnalysisEngine.java @@ -0,0 +1,157 @@ +/******************************************************************************* + * 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.j2ee.client.impl; + +import java.util.Iterator; +import java.util.jar.JarFile; + +import org.eclipse.jst.j2ee.commonarchivecore.internal.Archive; + +import com.ibm.wala.classLoader.JarFileModule; +import com.ibm.wala.classLoader.Module; +import com.ibm.wala.ipa.callgraph.AnalysisOptions; +import com.ibm.wala.ipa.callgraph.CallGraphBuilder; +import com.ibm.wala.ipa.cha.ClassHierarchy; +import com.ibm.wala.j2ee.DeploymentMetaData; +import com.ibm.wala.j2ee.J2EEAnalysisScope; +import com.ibm.wala.j2ee.client.AnalysisEngine; +import com.ibm.wala.j2ee.client.CallGraphBuilderFactory; +import com.ibm.wala.j2ee.util.TopLevelArchiveModule; +import com.ibm.wala.j2ee.util.TopLevelArchiveModule.BloatedArchiveModule; +import com.ibm.wala.types.ClassLoaderReference; +import com.ibm.wala.util.debug.Assertions; + +/** + * + * abstract base class for analysis engine implementations + * + * @author sfink + */ +public abstract class AbstractAnalysisEngine extends com.ibm.wala.client.impl.AbstractAnalysisEngine implements AnalysisEngine { + + /** + * A representation of the deployment descriptor + */ + private DeploymentMetaData dmd; + + /** + * The J2EE libraries to analysze + */ + private Module[] j2eeLibs; + + /** + * Should we analyze dependent jar files? + */ + private boolean dependentJars = true; + + protected AbstractAnalysisEngine() {} + + protected CallGraphBuilder getCallGraphBuilder(ClassHierarchy cha, AnalysisOptions options) { + return ((CallGraphBuilderFactory) getCallGraphBuilderFactory()).make(options, cha, (J2EEAnalysisScope) getScope(), getDmd(), + getWarnings(), false); + } + + /** + * Set up the AnalysisScope object + */ + protected void buildAnalysisScope() { + buildAnalysisScope(null); + } + /** + * Set up the AnalysisScope object + */ + protected void buildAnalysisScope(String exclusionsFile) { + // set up the scope of the analysis + ClassLoader cl = AbstractAnalysisEngine.class.getClassLoader(); + if (j2seLibs == null) { + Assertions.UNREACHABLE("no j2selibs specificed. You probably did not call AppAnalysisEngine.setJ2SELibrary."); + } else if (j2eeLibs == null) { + Assertions.UNREACHABLE("j2ee.jar is null. You probably did not call AnalysisEngine.setJ2EELibrary."); + } else { + scope = J2EEAnalysisScope.make(j2seLibs, j2eeLibs, exclusionsFile, cl, true); + } + + addApplicationModulesToScope(); + } + + /** + * Add the application modules to the analyis scope. + */ + @SuppressWarnings({ "restriction", "unchecked" }) + protected void addApplicationModulesToScope() { + ClassLoaderReference app = scope.getApplicationLoader(); + for (Iterator it = moduleFiles.iterator(); it.hasNext();) { + Archive A = (Archive) it.next(); + // TODO: redesign to avoid holding onto BloatedArchives? + TopLevelArchiveModule M = new BloatedArchiveModule(A); + if (!dependentJars) { + M.setIgnoreDependentJars(true); + } + scope.addToScope(app, M); + } + } + + /* + * (non-Javadoc) + * + * @see com.ibm.wala.atk.AppAnalysisEngine#setJ2EELibrary(java.util.jar.JarFile) + */ + public void setJ2EELibraries(JarFile[] libs) { + if (libs == null) { + Assertions.UNREACHABLE("Illegal to setJ2EELibrary(null)"); + } + this.j2eeLibs = new Module[libs.length]; + for (int i = 0; i < libs.length; i++) { + j2eeLibs[i] = new JarFileModule(libs[i]); + } + } + + public void setJ2EELibraries(Module[] libs) { + if (libs == null) { + Assertions.UNREACHABLE("Illegal to setJ2EELibrary(null)"); + } + this.j2eeLibs = new Module[libs.length]; + for (int i = 0; i < libs.length; i++) { + j2eeLibs[i] = libs[i]; + } + } + + /** + * @return Returns the dmd. + */ + protected DeploymentMetaData getDmd() { + return dmd; + } + + /** + * @param dmd + * The dmd to set. + */ + protected void setDmd(DeploymentMetaData dmd) { + this.dmd = dmd; + } + + /** + * @return Returns the dependentJars. + */ + public boolean isDependentJars() { + return dependentJars; + } + + /** + * @param dependentJars + * The dependentJars to set. + */ + public void setDependentJars(boolean dependentJars) { + this.dependentJars = dependentJars; + } + +} diff --git a/com.ibm.wala.j2ee/src/com/ibm/wala/j2ee/client/impl/ArrayContentsImpl.java b/com.ibm.wala.j2ee/src/com/ibm/wala/j2ee/client/impl/ArrayContentsImpl.java new file mode 100644 index 000000000..9202b9fc3 --- /dev/null +++ b/com.ibm.wala.j2ee/src/com/ibm/wala/j2ee/client/impl/ArrayContentsImpl.java @@ -0,0 +1,60 @@ +/******************************************************************************* + * 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.j2ee.client.impl; + +import com.ibm.wala.j2ee.client.IArrayContents; +import com.ibm.wala.j2ee.client.IClass; + +/** + * + * Object to track array contents in analysis results + * + * @author sfink + */ +public class ArrayContentsImpl implements IArrayContents { + + private final IClass klass; + + public ArrayContentsImpl(IClass klass) { + this.klass = klass; + } + + /* (non-Javadoc) + * @see com.ibm.wala.j2ee.client.IArrayContents#getDeclaredClass() + */ + public IClass getDeclaredClass() { + return klass; + } + + /* (non-Javadoc) + * @see java.lang.Object#toString() + */ + public String toString() { + return "ArrayContents:" + klass; + } + /* (non-Javadoc) + * @see java.lang.Object#equals(java.lang.Object) + */ + public boolean equals(Object arg0) { + if (getClass().equals(arg0.getClass())) { + ArrayContentsImpl that = (ArrayContentsImpl)arg0; + return klass.equals(that.klass); + } else { + return false; + } + } + /* (non-Javadoc) + * @see java.lang.Object#hashCode() + */ + public int hashCode() { + return 653 * klass.hashCode(); + } +} diff --git a/com.ibm.wala.j2ee/src/com/ibm/wala/j2ee/client/impl/CallGraphBuilderFactoryFactory.java b/com.ibm.wala.j2ee/src/com/ibm/wala/j2ee/client/impl/CallGraphBuilderFactoryFactory.java new file mode 100644 index 000000000..297734fec --- /dev/null +++ b/com.ibm.wala.j2ee/src/com/ibm/wala/j2ee/client/impl/CallGraphBuilderFactoryFactory.java @@ -0,0 +1,46 @@ +/******************************************************************************* + * 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.j2ee.client.impl; + +import java.util.Properties; + +import com.ibm.wala.j2ee.client.CallGraphBuilderFactory; +import com.ibm.wala.util.debug.Assertions; + +/** + * + * A factory for creating a call graph builder factory + * + * @author Stephen Fink + */ + +public class CallGraphBuilderFactoryFactory { + + /** + * Construct a CallGraphBuilderFactory + * + * @param props Optionally, influence the construction of the engine. + * @return A non-null AppAnalysisEngine instance. + */ + public static CallGraphBuilderFactory getCallGraphBuilderFactory(Properties props) { + try { + String klass = "com.ibm.wala.j2ee.client.impl.RTABuilderFactory"; + if (props != null) { + klass = props.getProperty("analysis", "com.ibm.wala.j2ee.client.impl.RTABuilderFactory"); + } + return (CallGraphBuilderFactory) Class.forName(klass).newInstance(); + } catch (Exception e) { + e.printStackTrace(); + Assertions.UNREACHABLE(); + return null; + } + } +} diff --git a/com.ibm.wala.j2ee/src/com/ibm/wala/j2ee/client/impl/ClassImpl.java b/com.ibm.wala.j2ee/src/com/ibm/wala/j2ee/client/impl/ClassImpl.java new file mode 100644 index 000000000..4a022af4a --- /dev/null +++ b/com.ibm.wala.j2ee/src/com/ibm/wala/j2ee/client/impl/ClassImpl.java @@ -0,0 +1,100 @@ +/******************************************************************************* + * 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.j2ee.client.impl; + +import com.ibm.wala.j2ee.client.IClass; +import com.ibm.wala.util.ImmutableByteArray; +import com.ibm.wala.util.StringStuff; + +/** + * + * A representation of a class used to communicate analysis results. + * + * @author sfink + */ +public class ClassImpl implements IClass { + + private final String classLoader; + private final String name; + private final String pack; + + /* + * (non-Javadoc) + * + * @see java.lang.Object#toString() + */ + public String toString() { + return name; + } + + public ClassImpl(com.ibm.wala.classLoader.IClass klass) { + this(klass.getReference().getName().toString(),klass.getClassLoader().getName().toString()); + } + + public ClassImpl(String name, String classLoader) { + this.classLoader = classLoader; + this.name = name; + String canon = StringStuff.deployment2CanonicalTypeString(name); + ImmutableByteArray b = StringStuff.parseForPackage(new ImmutableByteArray(canon.getBytes())); + this.pack = (b == null) ? null : b.toString(); + } + + /* + * (non-Javadoc) + * + * @see com.ibm.wala.atk.Method#getClassLoaderName() + */ + + public String getClassLoaderName() { + return classLoader; + } + + /* + * (non-Javadoc) + * + * @see com.ibm.wala.atk.Method#getName() + */ + public String getName() { + return name; + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#hashCode() + */ + public int hashCode() { + return getClassLoaderName().hashCode() * 4003 + getName().hashCode(); + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#equals(java.lang.Object) + */ + public boolean equals(Object arg0) { + if (getClass().equals(arg0.getClass())) { + ClassImpl other = (ClassImpl) arg0; + return getName().equals(other.getName()) && getClassLoaderName().equals(other.getClassLoaderName()); + } else { + return false; + } + } + + /* + * (non-Javadoc) + * + * @see com.ibm.wala.j2ee.client.IClass#getPackage() + */ + public String getPackage() { + return pack; + } +} \ No newline at end of file diff --git a/com.ibm.wala.j2ee/src/com/ibm/wala/j2ee/client/impl/FieldImpl.java b/com.ibm.wala.j2ee/src/com/ibm/wala/j2ee/client/impl/FieldImpl.java new file mode 100644 index 000000000..6caff7d8e --- /dev/null +++ b/com.ibm.wala.j2ee/src/com/ibm/wala/j2ee/client/impl/FieldImpl.java @@ -0,0 +1,47 @@ +/******************************************************************************* + * 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.j2ee.client.impl; + +import com.ibm.wala.j2ee.client.IField; +import com.ibm.wala.types.FieldReference; + +/** + * + * Object to track a field in analysis results + * + * @author sfink + */ +public class FieldImpl extends MemberImpl implements IField { + + /** + * @param f data structure representing a field + */ + public FieldImpl(FieldReference f) { + super(f); + } + /* (non-Javadoc) + * @see java.lang.Object#toString() + */ + public String toString() { + return getDeclaringClass() + "." + getName(); + } + /* (non-Javadoc) + * @see com.ibm.wala.j2ee.client.impl.MemberImpl#equals(java.lang.Object) + */ + public boolean equals(Object arg0) { + if (getClass().equals(arg0.getClass())) { + FieldImpl other = (FieldImpl)arg0; + return getName().equals(other.getName()) && getClassLoaderName().equals(other.getClassLoaderName()); + } else { + return false; + } + } +} diff --git a/com.ibm.wala.j2ee/src/com/ibm/wala/j2ee/client/impl/MemberImpl.java b/com.ibm.wala.j2ee/src/com/ibm/wala/j2ee/client/impl/MemberImpl.java new file mode 100644 index 000000000..c904041c4 --- /dev/null +++ b/com.ibm.wala.j2ee/src/com/ibm/wala/j2ee/client/impl/MemberImpl.java @@ -0,0 +1,63 @@ +/******************************************************************************* + * 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.j2ee.client.impl; + +import com.ibm.wala.j2ee.client.IClass; +import com.ibm.wala.types.MemberReference; + +/** + * + * A representation of a field used to communicate analysis results. + * + * @author sfink + */ +public abstract class MemberImpl { + + private final IClass declaringClass; + private final String name; + + public MemberImpl(MemberReference m) { + this.declaringClass = new ClassImpl(m.getType().getName().toString(),m.getType().getClassLoader().getName().toString()); + this.name = m.getName().toString(); + } + + /* (non-Javadoc) + * @see com.ibm.wala.atk.Method#getDeclaringClass() + */ + public IClass getDeclaringClass() { + return declaringClass; + } + + /* (non-Javadoc) + * @see com.ibm.wala.atk.Method#getClassLoaderName() + */ + public String getClassLoaderName() { + return declaringClass.getClassLoaderName(); + } + + /* (non-Javadoc) + * @see com.ibm.wala.atk.Method#getName() + */ + public String getName() { + return name; + } + + /* (non-Javadoc) + * @see java.lang.Object#hashCode() + */ + public int hashCode() { + return getDeclaringClass().hashCode() * 4001 + getClassLoaderName().hashCode() * 4003 + getName().hashCode(); + } + /* (non-Javadoc) + * @see java.lang.Object#equals(java.lang.Object) + */ + public abstract boolean equals(Object arg0); +} diff --git a/com.ibm.wala.j2ee/src/com/ibm/wala/j2ee/client/impl/MethodImpl.java b/com.ibm.wala.j2ee/src/com/ibm/wala/j2ee/client/impl/MethodImpl.java new file mode 100644 index 000000000..1625e9c6e --- /dev/null +++ b/com.ibm.wala.j2ee/src/com/ibm/wala/j2ee/client/impl/MethodImpl.java @@ -0,0 +1,94 @@ +/******************************************************************************* + * 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.j2ee.client.impl; + +import com.ibm.wala.j2ee.client.IMethod; +import com.ibm.wala.types.MethodReference; + +/** + * + * A representation of a method used to communicate analysis results. + * + * @author sfink + */ +public class MethodImpl extends MemberImpl implements IMethod { + + private final String descriptor; + + public MethodImpl(MethodReference M) { + super(M); + descriptor = M.getDescriptor().toString(); + } + + /* + * (non-Javadoc) + * + * @see com.ibm.wala.atk.Method#getDescriptor() + */ + public String getDescriptor() { + return descriptor; + } + + /** + * A signature is a string like: + * com.foo.bar.createLargeOrder(IILjava.lang.String;SLjava.sql.Date;)Ljava.lang.Integer; + * + * @return String representation of the signature + */ + public String getSignature() { + String s = getDeclaringClass().toString().substring(1).replace('/', '.') + "." + getName() + getDescriptor(); + return s; + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#toString() + */ + public String toString() { + return getSignature(); + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#equals(java.lang.Object) + */ + public boolean equals(Object arg0) { + if (getClass().equals(arg0.getClass())) { + MethodImpl other = (MethodImpl) arg0; + return getDeclaringClass().equals(other.getDeclaringClass()) && getClassLoaderName().equals(other.getClassLoaderName()) + && getName().equals(other.getName()) && descriptor.equals(other.descriptor); + } else { + return false; + } + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#hashCode() + */ + public int hashCode() { + return getDeclaringClass().hashCode() * 4001 + getClassLoaderName().hashCode() * 4003 + getName().hashCode() + + descriptor.hashCode(); + } + + /* + * (non-Javadoc) + * + * @see com.ibm.wala.j2ee.client.IMethod#getSelector() + */ + public String getSelector() { + return getName() + descriptor; + } + +} diff --git a/com.ibm.wala.j2ee/src/com/ibm/wala/j2ee/client/impl/ProgramLocation.java b/com.ibm.wala.j2ee/src/com/ibm/wala/j2ee/client/impl/ProgramLocation.java new file mode 100644 index 000000000..9c3b7a9e4 --- /dev/null +++ b/com.ibm.wala.j2ee/src/com/ibm/wala/j2ee/client/impl/ProgramLocation.java @@ -0,0 +1,69 @@ +/******************************************************************************* + * 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.j2ee.client.impl; + +import com.ibm.wala.j2ee.client.IMethod; +import com.ibm.wala.j2ee.client.IProgramLocation; + +/** + * @author sfink + */ +public class ProgramLocation implements IProgramLocation { + + private final IMethod method; + + private final int bytecodeIndex; + + private final int lineNumber; + + public ProgramLocation(IMethod method, int bytecodeIndex, int lineNumber) { + this.method = method; + this.bytecodeIndex = bytecodeIndex; + this.lineNumber = lineNumber; + } + + /* + * (non-Javadoc) + * + * @see com.ibm.wala.j2ee.client.IProgramLocation#getMethod() + */ + public IMethod getMethod() { + return method; + } + + /* + * (non-Javadoc) + * + * @see com.ibm.wala.j2ee.client.IProgramLocation#getBytecodeIndex() + */ + public int getBytecodeIndex() { + return bytecodeIndex; + } + + /* + * (non-Javadoc) + * + * @see com.ibm.wala.j2ee.client.IProgramLocation#getLineNumber() + */ + public int getLineNumber() { + return lineNumber; + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#toString() + */ + public String toString() { + return method + "@" + bytecodeIndex + "(line " + lineNumber + ")"; + } + +} \ No newline at end of file diff --git a/com.ibm.wala.j2ee/src/com/ibm/wala/j2ee/client/impl/RTABuilderFactory.java b/com.ibm.wala.j2ee/src/com/ibm/wala/j2ee/client/impl/RTABuilderFactory.java new file mode 100644 index 000000000..6af5c1bbf --- /dev/null +++ b/com.ibm.wala.j2ee/src/com/ibm/wala/j2ee/client/impl/RTABuilderFactory.java @@ -0,0 +1,47 @@ +/******************************************************************************* + * 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.j2ee.client.impl; + +import com.ibm.wala.ipa.callgraph.AnalysisOptions; +import com.ibm.wala.ipa.callgraph.CallGraphBuilder; +import com.ibm.wala.ipa.cha.ClassHierarchy; +import com.ibm.wala.j2ee.DeploymentMetaData; +import com.ibm.wala.j2ee.J2EEAnalysisScope; +import com.ibm.wala.j2ee.client.CallGraphBuilderFactory; +import com.ibm.wala.j2ee.util.Util; +import com.ibm.wala.util.warnings.WarningSet; + +/** + * + * A factory to create J2EE call graph builders using RTA + * + * @author sfink + */ +public class RTABuilderFactory + extends com.ibm.wala.client.impl.RTABuilderFactory + implements CallGraphBuilderFactory +{ + + /* + * (non-Javadoc) + * + * @see com.ibm.wala.j2ee.client.CallGraphBuilderFactory#make(com.ibm.wala.ipa.callgraph.AnalysisOptions, + * com.ibm.wala.ipa.cha.ClassHierarchy, java.lang.ClassLoader, + * com.ibm.wala.j2ee.J2EEAnalysisScope, + * com.ibm.wala.j2ee.DeploymentMetaData, + * com.ibm.wala.util.warnings.WarningSet, boolean) + */ + public CallGraphBuilder make(AnalysisOptions options, ClassHierarchy cha, J2EEAnalysisScope scope, + DeploymentMetaData dmd, WarningSet warnings, boolean keepPointsTo) { + return Util.makeRTABuilder(options, cha, getClass().getClassLoader(), scope, dmd, warnings); + } + +} diff --git a/com.ibm.wala.j2ee/src/com/ibm/wala/j2ee/client/impl/ZeroCFABuilderFactory.java b/com.ibm.wala.j2ee/src/com/ibm/wala/j2ee/client/impl/ZeroCFABuilderFactory.java new file mode 100644 index 000000000..62b43fbb9 --- /dev/null +++ b/com.ibm.wala.j2ee/src/com/ibm/wala/j2ee/client/impl/ZeroCFABuilderFactory.java @@ -0,0 +1,44 @@ +/******************************************************************************* + * 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.j2ee.client.impl; + +import com.ibm.wala.ipa.callgraph.AnalysisOptions; +import com.ibm.wala.ipa.callgraph.CallGraphBuilder; +import com.ibm.wala.ipa.cha.ClassHierarchy; +import com.ibm.wala.j2ee.DeploymentMetaData; +import com.ibm.wala.j2ee.J2EEAnalysisScope; +import com.ibm.wala.j2ee.client.CallGraphBuilderFactory; +import com.ibm.wala.j2ee.util.Util; +import com.ibm.wala.util.warnings.WarningSet; + +/** + * @author sfink + */ +public class ZeroCFABuilderFactory + extends com.ibm.wala.client.impl.ZeroCFABuilderFactory + implements CallGraphBuilderFactory +{ + + /* + * (non-Javadoc) + * + * @see com.ibm.wala.j2ee.client.CallGraphBuilderFactory#make(com.ibm.wala.ipa.callgraph.AnalysisOptions, + * com.ibm.wala.ipa.cha.ClassHierarchy, java.lang.ClassLoader, + * com.ibm.wala.j2ee.J2EEAnalysisScope, + * com.ibm.wala.j2ee.DeploymentMetaData, + * com.ibm.wala.util.warnings.WarningSet, boolean) + */ + public CallGraphBuilder make(AnalysisOptions options, ClassHierarchy cha, J2EEAnalysisScope scope, + DeploymentMetaData dmd, WarningSet warnings, boolean keepPointsTo) { + return Util.makeZeroCFABuilder(options, cha, getClass().getClassLoader(), scope, dmd, warnings); + } + +} diff --git a/com.ibm.wala.j2ee/src/com/ibm/wala/j2ee/client/impl/ZeroContainerCFABuilderFactory.java b/com.ibm.wala.j2ee/src/com/ibm/wala/j2ee/client/impl/ZeroContainerCFABuilderFactory.java new file mode 100644 index 000000000..7d1845845 --- /dev/null +++ b/com.ibm.wala.j2ee/src/com/ibm/wala/j2ee/client/impl/ZeroContainerCFABuilderFactory.java @@ -0,0 +1,47 @@ +/******************************************************************************* + * 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.j2ee.client.impl; + +import com.ibm.wala.ipa.callgraph.AnalysisOptions; +import com.ibm.wala.ipa.callgraph.CallGraphBuilder; +import com.ibm.wala.ipa.cha.ClassHierarchy; +import com.ibm.wala.j2ee.DeploymentMetaData; +import com.ibm.wala.j2ee.J2EEAnalysisScope; +import com.ibm.wala.j2ee.client.CallGraphBuilderFactory; +import com.ibm.wala.j2ee.util.Util; +import com.ibm.wala.util.warnings.WarningSet; + +/** + * + * A factory to create J2EE call graph builders using 0-1-container-CFA + * + * @author sfink + */ +public class ZeroContainerCFABuilderFactory + extends com.ibm.wala.client.impl.ZeroContainerCFABuilderFactory + implements CallGraphBuilderFactory +{ + + /* + * (non-Javadoc) + * + * @see com.ibm.wala.j2ee.client.CallGraphBuilderFactory#make(com.ibm.wala.ipa.callgraph.AnalysisOptions, + * com.ibm.wala.ipa.cha.ClassHierarchy, java.lang.ClassLoader, + * com.ibm.wala.j2ee.J2EEAnalysisScope, + * com.ibm.wala.j2ee.DeploymentMetaData, + * com.ibm.wala.util.warnings.WarningSet, boolean) + */ + public CallGraphBuilder make(AnalysisOptions options, ClassHierarchy cha, J2EEAnalysisScope scope, DeploymentMetaData dmd, + WarningSet warnings, boolean keepPointsTo) { + return Util.makeZeroContainerCFABuilder(options, cha, getClass().getClassLoader(), scope, dmd, warnings); + } + +} diff --git a/com.ibm.wala.j2ee/src/com/ibm/wala/j2ee/client/impl/ZeroOneCFABuilderFactory.java b/com.ibm.wala.j2ee/src/com/ibm/wala/j2ee/client/impl/ZeroOneCFABuilderFactory.java new file mode 100644 index 000000000..398e69d53 --- /dev/null +++ b/com.ibm.wala.j2ee/src/com/ibm/wala/j2ee/client/impl/ZeroOneCFABuilderFactory.java @@ -0,0 +1,46 @@ +/******************************************************************************* + * 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.j2ee.client.impl; + +import com.ibm.wala.ipa.callgraph.AnalysisOptions; +import com.ibm.wala.ipa.callgraph.CallGraphBuilder; +import com.ibm.wala.ipa.cha.ClassHierarchy; +import com.ibm.wala.j2ee.DeploymentMetaData; +import com.ibm.wala.j2ee.J2EEAnalysisScope; +import com.ibm.wala.j2ee.client.CallGraphBuilderFactory; +import com.ibm.wala.j2ee.util.Util; +import com.ibm.wala.util.warnings.WarningSet; + +/** + * A factory to create J2EE call graph builders using 0-1-container-CFA + * + * @author sfink + */ +public class ZeroOneCFABuilderFactory + extends com.ibm.wala.client.impl.ZeroOneCFABuilderFactory + implements CallGraphBuilderFactory +{ + + /* + * (non-Javadoc) + * + * @see com.ibm.wala.j2ee.client.CallGraphBuilderFactory#make(com.ibm.wala.ipa.callgraph.AnalysisOptions, + * com.ibm.wala.ipa.cha.ClassHierarchy, java.lang.ClassLoader, + * com.ibm.wala.j2ee.J2EEAnalysisScope, + * com.ibm.wala.j2ee.DeploymentMetaData, + * com.ibm.wala.util.warnings.WarningSet, boolean) + */ + public CallGraphBuilder make(AnalysisOptions options, ClassHierarchy cha, J2EEAnalysisScope scope, + DeploymentMetaData dmd, WarningSet warnings, boolean keepPointsTo) { + return Util.makeZeroOneCFABuilder(options, cha, getClass().getClassLoader(), scope, dmd, warnings); + } + +} diff --git a/com.ibm.wala.j2ee/src/com/ibm/wala/j2ee/client/impl/ZeroOneContainerCFABuilderFactory.java b/com.ibm.wala.j2ee/src/com/ibm/wala/j2ee/client/impl/ZeroOneContainerCFABuilderFactory.java new file mode 100644 index 000000000..dc24c1c64 --- /dev/null +++ b/com.ibm.wala.j2ee/src/com/ibm/wala/j2ee/client/impl/ZeroOneContainerCFABuilderFactory.java @@ -0,0 +1,46 @@ +/******************************************************************************* + * 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.j2ee.client.impl; + +import com.ibm.wala.ipa.callgraph.AnalysisOptions; +import com.ibm.wala.ipa.callgraph.CallGraphBuilder; +import com.ibm.wala.ipa.cha.ClassHierarchy; +import com.ibm.wala.j2ee.DeploymentMetaData; +import com.ibm.wala.j2ee.J2EEAnalysisScope; +import com.ibm.wala.j2ee.client.CallGraphBuilderFactory; +import com.ibm.wala.j2ee.util.Util; +import com.ibm.wala.util.warnings.WarningSet; + +/** + * + * + * @author sfink + */ +public class ZeroOneContainerCFABuilderFactory + extends com.ibm.wala.client.impl.ZeroOneContainerCFABuilderFactory + implements CallGraphBuilderFactory +{ + + /* + * (non-Javadoc) + * + * @see com.ibm.wala.j2ee.client.CallGraphBuilderFactory#make(com.ibm.wala.ipa.callgraph.AnalysisOptions, + * com.ibm.wala.ipa.cha.ClassHierarchy, java.lang.ClassLoader, + * com.ibm.wala.j2ee.J2EEAnalysisScope, + * com.ibm.wala.j2ee.DeploymentMetaData, + * com.ibm.wala.util.warnings.WarningSet, boolean) + */ + public CallGraphBuilder make(AnalysisOptions options, ClassHierarchy cha, J2EEAnalysisScope scope, DeploymentMetaData dmd, + WarningSet warnings, boolean keepPointsTo) { + return Util.makeZeroOneContainerCFABuilder(options, cha, getClass().getClassLoader(), scope, dmd, warnings); + } + +} diff --git a/com.ibm.wala.j2ee/src/com/ibm/wala/j2ee/util/TopLevelArchiveModule.java b/com.ibm.wala.j2ee/src/com/ibm/wala/j2ee/util/TopLevelArchiveModule.java new file mode 100644 index 000000000..de70d335c --- /dev/null +++ b/com.ibm.wala.j2ee/src/com/ibm/wala/j2ee/util/TopLevelArchiveModule.java @@ -0,0 +1,308 @@ +// Licensed Materials - Property of IBM +// 5724-D15 +// (C) Copyright IBM Corporation 2004. All Rights Reserved. +// Note to U.S. Government Users Restricted Rights: Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp. +// +// --------------------------------------------------------------------------- + +package com.ibm.wala.j2ee.util; + +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.util.Collection; +import java.util.HashSet; +import java.util.Iterator; + +import org.eclipse.jst.j2ee.commonarchivecore.internal.ApplicationClientFile; +import org.eclipse.jst.j2ee.commonarchivecore.internal.Archive; +import org.eclipse.jst.j2ee.commonarchivecore.internal.EARFile; +import org.eclipse.jst.j2ee.commonarchivecore.internal.EJBJarFile; +import org.eclipse.jst.j2ee.commonarchivecore.internal.File; +import org.eclipse.jst.j2ee.commonarchivecore.internal.WARFile; + +import com.ibm.wala.classLoader.JarFileModule; +import com.ibm.wala.classLoader.Module; +import com.ibm.wala.classLoader.ModuleEntry; +import com.ibm.wala.j2ee.J2EEUtil; +import com.ibm.wala.util.debug.Assertions; +import com.ibm.wala.util.debug.Trace; +import com.ibm.wala.util.io.FileSuffixes; + +/** + * + * A wrapper around a WCCM Archive. + * + * @author sfink + */ +public class TopLevelArchiveModule implements Module { + + /** + * Path to classpath root in a war + */ + private static final String WAR_CP_ROOT = "WEB-INF/classes/"; + + /** + * Path into which WSAD generates JSP implementations + */ + private static final String WAR_JSP_CP_ROOT = "WEB-INF/classes/WEB-INF/"; + + private static final String ORG_APACHE_JSP = "org/apache/jsp/"; + + public final static byte WAR_FILE = 0; + public final static byte OTHER_JAR_FILE = 1; + public final static byte APPLICATION_CLIENT_FILE = 2; + public final static byte EAR_FILE = 3; + public final static byte EJB_JAR_FILE = 4; + + private boolean ignoreDependentJars = false; + + + private static final boolean DEBUG = false; + /** + * The JarFileModule that represents this archive. + * If this is null, it means that this is a nested archive. + * TODO: We'll need to clean up the class hierarchy so that BloatedArchive + * does not extend TopLevelArchive ... in which case we can assert that + * jarFile != null; + */ + private final JarFileModule jarFile; + + public TopLevelArchiveModule(JarFileModule jarFile) { + this.jarFile = jarFile; + } + + /** + * @param A an ARCHIVE + * @return one of EAR_FILE, JAR_FILE, WAR_FILE, or APPLICATION_CLIENT_FILE + */ + @SuppressWarnings("restriction") + public static byte getTypeCode(Archive A) { + if (A instanceof EARFile) { + return EAR_FILE; + } else if (A instanceof EJBJarFile) { + return EJB_JAR_FILE; + } else if (A instanceof WARFile) { + return WAR_FILE; + } else if (A instanceof ApplicationClientFile) { + return APPLICATION_CLIENT_FILE; + } else { + return OTHER_JAR_FILE; + } + } + + /* (non-Javadoc) + * @see java.lang.Object#toString() + */ + @SuppressWarnings("restriction") + public String toString() { + return "ArchiveModule:" + materializeArchive().getName(); + } + + /** + * @return one of EAR_FILE, JAR_FILE, WAR_FILE, or APPLICATION_CLIENT_FILE + */ + public byte getType() { + return getTypeCode(materializeArchive()); + } + + /* (non-Javadoc) + * @see com.ibm.wala.classLoader.Module#getEntries() + */ + @SuppressWarnings({ "restriction", "unchecked" }) + public Iterator getEntries() { + if (DEBUG) { + Trace.println("ArchiveModule.getEntries(): " + this); + } + Archive A = materializeArchive(); + Collection files = A.getFiles(); + Collection entries = new HashSet(files.size()); + for (Iterator it = files.iterator(); it.hasNext(); ) { + File f = (File)it.next(); + if (f.isArchive()) { + byte code = getTypeCode((Archive)f); + if (ignoreDependentJars && code == OTHER_JAR_FILE) { + continue; + } + } + entries.add(new Entry(f)); + } + return entries.iterator(); + } + + /** + * @return a WCCM Archive representing this module + */ + public Archive materializeArchive() { + return J2EEUtil.getArchive(jarFile); + } + + /** + * @return true iff the jar file suffix is .war + */ + protected boolean isWarFile() { + if (jarFile == null) { + // this is a nested archive which should override this method. + Assertions.UNREACHABLE(); + return false; + } + return jarFile.getJarFile().getName().indexOf(".war") > -1; + } + + /** + * @param b + */ + public void setIgnoreDependentJars(boolean b) { + ignoreDependentJars = b; + } + + private class Entry implements ModuleEntry { + + private File F; + + Entry(File F) { + this.F = F; + } + + /* (non-Javadoc) + * @see com.ibm.wala.classLoader.ModuleEntry#getName() + */ + @SuppressWarnings("restriction") + public String getName() { + return F.getURI(); + } + + /* (non-Javadoc) + * @see com.ibm.wala.classLoader.ModuleEntry#isClassFile() + */ + @SuppressWarnings("restriction") + public boolean isClassFile() { + return FileSuffixes.isClassFile(F.getName()); + } + + /* (non-Javadoc) + * @see com.ibm.wala.classLoader.ModuleEntry#getInputStream() + */ + @SuppressWarnings("restriction") + public InputStream getInputStream() { + try { + return F.getInputStream(); + } catch (FileNotFoundException e) { + e.printStackTrace(); + Assertions.UNREACHABLE(); + return null; + } catch (IOException e) { + e.printStackTrace(); + Assertions.UNREACHABLE(); + return null; + } + } + + /* (non-Javadoc) + * @see java.lang.Object#toString() + */ + public String toString() { + return getName(); + } + + /* (non-Javadoc) + * @see com.ibm.wala.classLoader.ModuleEntry#isModuleFile() + */ + @SuppressWarnings("restriction") + public boolean isModuleFile() { + return F.isArchive(); + } + + /* (non-Javadoc) + * @see com.ibm.wala.classLoader.ModuleEntry#asModule() + */ + @SuppressWarnings("restriction") + public Module asModule() { + if (Assertions.verifyAssertions) { + Assertions._assert(isModuleFile()); + } + return new BloatedArchiveModule((Archive) F); + } + + /* (non-Javadoc) + * @see com.ibm.wala.classLoader.ModuleEntry#getClassName() + */ + public String getClassName() { + String name = getName(); + if (isWarFile()) { + if (name.indexOf("/") == 0) { + name = name.substring(1); + } + if (name.indexOf(WAR_JSP_CP_ROOT) == 0) { + // this should be a JSP implementation. + name = name.substring(WAR_JSP_CP_ROOT.length()); + name = ORG_APACHE_JSP + name; + } else if (name.indexOf(WAR_CP_ROOT) == 0) { + name = name.substring(WAR_CP_ROOT.length()); + // if it looks like the default package, assume it's a jsp. + if (name.indexOf("/") == -1) { + name = ORG_APACHE_JSP + name; + } + } + } + return FileSuffixes.stripSuffix(name); + } + /* (non-Javadoc) + * @see java.lang.Object#hashCode() + */ + public int hashCode() { + return F.hashCode() * 593; + } + + /* (non-Javadoc) + * @see com.ibm.wala.classLoader.ModuleEntry#isSourceFile() + */ + public boolean isSourceFile() { + return false; + } + + } + + // TODO: clean up this class hierarchy; it sucks. + // an instance of BloatedArchiveModule should not be held onto for long. + public static class BloatedArchiveModule extends TopLevelArchiveModule { + + private final Archive A; + + public BloatedArchiveModule(Archive A) { + super(null); + this.A = A; + } + + /* (non-Javadoc) + * @see com.ibm.wala.j2ee.util.TopLevelArchiveModule#materializeArchive() + */ + public Archive materializeArchive() { + return A; + } + + /* (non-Javadoc) + * @see com.ibm.wala.j2ee.util.TopLevelArchiveModule#isWarFile() + */ + protected boolean isWarFile() { + return getTypeCode(A) == WAR_FILE; + } + /* (non-Javadoc) + * @see com.ibm.wala.j2ee.util.TopLevelArchiveModule#isWarFile() + */ + protected boolean isApplicationClientFile() { + return getTypeCode(A) == APPLICATION_CLIENT_FILE; + } + + + /* (non-Javadoc) + * @see java.lang.Object#hashCode() + */ + public int hashCode() { + return A.hashCode() * 2027; + } + + } + + +} diff --git a/com.ibm.wala.j2ee/src/com/ibm/wala/j2ee/util/Util.java b/com.ibm.wala.j2ee/src/com/ibm/wala/j2ee/util/Util.java new file mode 100644 index 000000000..e05f8acf1 --- /dev/null +++ b/com.ibm.wala.j2ee/src/com/ibm/wala/j2ee/util/Util.java @@ -0,0 +1,330 @@ +// Licensed Materials - Property of IBM +// 5724-D15 +// (C) Copyright IBM Corporation 2004. All Rights Reserved. +// Note to U.S. Government Users Restricted Rights: Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp. +// +// --------------------------------------------------------------------------- + +package com.ibm.wala.j2ee.util; + +import java.util.Set; + +import com.ibm.wala.analysis.typeInference.ReceiverTypeInferenceCache; +import com.ibm.wala.classLoader.IClass; +import com.ibm.wala.ipa.callgraph.AnalysisOptions; +import com.ibm.wala.ipa.callgraph.AnalysisScope; +import com.ibm.wala.ipa.callgraph.CallGraphBuilder; +import com.ibm.wala.ipa.callgraph.ClassTargetSelector; +import com.ibm.wala.ipa.callgraph.ContextSelector; +import com.ibm.wala.ipa.callgraph.MethodTargetSelector; +import com.ibm.wala.ipa.callgraph.propagation.SSAContextInterpreter; +import com.ibm.wala.ipa.callgraph.propagation.cfa.CFABuilder; +import com.ibm.wala.ipa.callgraph.propagation.cfa.OneCFABuilder; +import com.ibm.wala.ipa.callgraph.propagation.cfa.ZeroContainerCFABuilder; +import com.ibm.wala.ipa.callgraph.propagation.cfa.ZeroOneContainerCFABuilder; +import com.ibm.wala.ipa.callgraph.propagation.cfa.ZeroXCFABuilder; +import com.ibm.wala.ipa.callgraph.propagation.cfa.ZeroXInstanceKeys; +import com.ibm.wala.ipa.callgraph.propagation.rta.BasicRTABuilder; +import com.ibm.wala.ipa.cha.ClassHierarchy; +import com.ibm.wala.ipa.cha.ClassHierarchyException; +import com.ibm.wala.j2ee.BeanMetaData; +import com.ibm.wala.j2ee.CommandInterpreter; +import com.ibm.wala.j2ee.DeploymentMetaData; +import com.ibm.wala.j2ee.J2EEClassTargetSelector; +import com.ibm.wala.j2ee.J2EEContextSelector; +import com.ibm.wala.j2ee.J2EEMethodTargetSelector; +import com.ibm.wala.types.TypeReference; +import com.ibm.wala.util.Atom; +import com.ibm.wala.util.collections.HashSetFactory; +import com.ibm.wala.util.debug.Assertions; +import com.ibm.wala.util.warnings.WarningSet; + +/** + * @author sfink + */ +public class Util { + + /** + * @return an RTA Call Graph builder. + * + * @param options + * options that govern call graph construction + * @param cha + * governing class hierarchy + * @param cl + * classloader that can find WALA resources + * @param scope + * representation of the analysis scope + * @param dmd + * deployment descriptor abstraction + * @param warnings + * an object which tracks analysis warnings + */ + public static CallGraphBuilder makeRTABuilder(AnalysisOptions options, ClassHierarchy cha, ClassLoader cl, AnalysisScope scope, + DeploymentMetaData dmd, WarningSet warnings) { + + com.ibm.wala.ipa.callgraph.impl.Util.addDefaultSelectors(options, cha, warnings); + addDefaultJ2EEBypassLogic(options, scope, cl, cha); + ContextSelector appSelector = null; + SSAContextInterpreter appInterpreter = null; + if (dmd != null) { + ReceiverTypeInferenceCache typeInference = new ReceiverTypeInferenceCache(cha, options, warnings); + addJ2EEBypassLogic(options, scope, dmd, cha, typeInference, warnings); + appSelector = new J2EEContextSelector(typeInference, warnings); + appInterpreter = new CommandInterpreter(cha, warnings); + } + + return new BasicRTABuilder(cha, warnings, options, appSelector, appInterpreter); + } + + /** + * @param options + * options that govern call graph construction + * @param cha + * governing class hierarchy + * @param cl + * classloader that can find WALA resources + * @param scope + * representation of the analysis scope + * @param dmd + * deployment descriptor abstraction + * @param warnings + * an object which tracks analysis warnings + * @return a 0-CFA Call Graph Builder. + */ + public static CFABuilder makeZeroCFABuilder(AnalysisOptions options, ClassHierarchy cha, ClassLoader cl, AnalysisScope scope, + DeploymentMetaData dmd, WarningSet warnings) { + + com.ibm.wala.ipa.callgraph.impl.Util.addDefaultSelectors(options, cha, warnings); + addDefaultJ2EEBypassLogic(options, scope, cl, cha); + ContextSelector appSelector = null; + SSAContextInterpreter appInterpreter = null; + if (dmd != null) { + ReceiverTypeInferenceCache typeInference = new ReceiverTypeInferenceCache(cha, options, warnings); + addJ2EEBypassLogic(options, scope, dmd, cha, typeInference, warnings); + appSelector = new J2EEContextSelector(typeInference, warnings); + appInterpreter = new CommandInterpreter(cha, warnings); + } + + return new ZeroXCFABuilder(cha, warnings, options, appSelector, appInterpreter, options.getReflectionSpec(), + ZeroXInstanceKeys.NONE); + } + + /** + * @param options + * options that govern call graph construction + * @param cha + * governing class hierarchy + * @param cl + * classloader that can find WALA resources + * @param scope + * representation of the analysis scope + * @param dmd + * deployment descriptor abstraction + * @param warnings + * an object which tracks analysis warnings + * @return a 1-CFA Call Graph Builder. + */ + public static CallGraphBuilder makeOneCFABuilder(AnalysisOptions options, ClassHierarchy cha, ClassLoader cl, + AnalysisScope scope, DeploymentMetaData dmd, WarningSet warnings) { + + com.ibm.wala.ipa.callgraph.impl.Util.addDefaultSelectors(options, cha, warnings); + addDefaultJ2EEBypassLogic(options, scope, cl, cha); + ContextSelector appSelector = null; + SSAContextInterpreter appInterpreter = null; + if (dmd != null) { + ReceiverTypeInferenceCache typeInference = new ReceiverTypeInferenceCache(cha, options, warnings); + addJ2EEBypassLogic(options, scope, dmd, cha, typeInference, warnings); + appSelector = new J2EEContextSelector(typeInference, warnings); + appInterpreter = new CommandInterpreter(cha, warnings); + } + + CallGraphBuilder builder = new OneCFABuilder(cha, warnings, options, appSelector, appInterpreter, options.getReflectionSpec()); + return builder; + } + + /** + * @param options + * options that govern call graph construction + * @param cha + * governing class hierarchy + * @param cl + * classloader that can find WALA resources + * @param scope + * representation of the analysis scope + * @param dmd + * deployment descriptor abstraction + * @param warnings + * an object which tracks analysis warnings + * @return a 0-1-CFA Call Graph Builder. + * + * This version uses the DEDUCED_PLUS_STRINGSTUFF policy to avoid + * disambiguating uninteresting types. + */ + public static CFABuilder makeZeroOneCFABuilder(AnalysisOptions options, ClassHierarchy cha, ClassLoader cl, AnalysisScope scope, + DeploymentMetaData dmd, WarningSet warnings) { + + com.ibm.wala.ipa.callgraph.impl.Util.addDefaultSelectors(options, cha, warnings); + addDefaultJ2EEBypassLogic(options, scope, cl, cha); + ContextSelector appSelector = null; + SSAContextInterpreter appInterpreter = null; + if (dmd != null) { + ReceiverTypeInferenceCache typeInference = new ReceiverTypeInferenceCache(cha, options, warnings); + addJ2EEBypassLogic(options, scope, dmd, cha, typeInference, warnings); + appSelector = new J2EEContextSelector(typeInference, warnings); + appInterpreter = new CommandInterpreter(cha, warnings); + } + + return new ZeroXCFABuilder(cha, warnings, options, appSelector, appInterpreter, options.getReflectionSpec(), + ZeroXInstanceKeys.ALLOCATIONS | ZeroXInstanceKeys.SMUSH_MANY | ZeroXInstanceKeys.SMUSH_PRIMITIVE_HOLDERS + | ZeroXInstanceKeys.SMUSH_STRINGS | ZeroXInstanceKeys.SMUSH_THROWABLES); + } + + /** + * @param options + * options that govern call graph construction + * @param cha + * governing class hierarchy + * @param cl + * classloader that can find WALA resources + * @param scope + * representation of the analysis scope + * @param dmd + * deployment descriptor abstraction + * @param warnings + * an object which tracks analysis warnings + * @return a 0-1-CFA Call Graph Builder. + * + * This version uses the ALL policy to disambiguate all allocation sites + */ + public static CFABuilder makeZeroOneUnoptCFABuilder(AnalysisOptions options, ClassHierarchy cha, ClassLoader cl, + AnalysisScope scope, DeploymentMetaData dmd, WarningSet warnings) { + + com.ibm.wala.ipa.callgraph.impl.Util.addDefaultSelectors(options, cha, warnings); + addDefaultJ2EEBypassLogic(options, scope, cl, cha); + ContextSelector appSelector = null; + SSAContextInterpreter appInterpreter = null; + if (dmd != null) { + ReceiverTypeInferenceCache typeInference = new ReceiverTypeInferenceCache(cha, options, warnings); + addJ2EEBypassLogic(options, scope, dmd, cha, typeInference, warnings); + appSelector = new J2EEContextSelector(typeInference, warnings); + appInterpreter = new CommandInterpreter(cha, warnings); + } + + return new ZeroXCFABuilder(cha, warnings, options, appSelector, appInterpreter, options.getReflectionSpec(), + ZeroXInstanceKeys.ALLOCATIONS); + } + + /** + * @param options + * options that govern call graph construction + * @param cha + * governing class hierarchy + * @param cl + * classloader that can find WALA resources + * @param scope + * representation of the analysis scope + * @param dmd + * deployment descriptor abstraction + * @param warnings + * an object which tracks analysis warnings + * @return a 0-CFA Call Graph Builder augmented with extra logic for + * containers + */ + public static CFABuilder makeZeroContainerCFABuilder(AnalysisOptions options, ClassHierarchy cha, ClassLoader cl, + AnalysisScope scope, DeploymentMetaData dmd, WarningSet warnings) { + + com.ibm.wala.ipa.callgraph.impl.Util.addDefaultSelectors(options, cha, warnings); + addDefaultJ2EEBypassLogic(options, scope, cl, cha); + ContextSelector appSelector = null; + SSAContextInterpreter appInterpreter = null; + if (dmd != null) { + ReceiverTypeInferenceCache typeInference = new ReceiverTypeInferenceCache(cha, options, warnings); + addJ2EEBypassLogic(options, scope, dmd, cha, typeInference, warnings); + appSelector = new J2EEContextSelector(typeInference, warnings); + appInterpreter = new CommandInterpreter(cha, warnings); + } + + return new ZeroContainerCFABuilder(cha, warnings, options, appSelector, appInterpreter, options.getReflectionSpec()); + } + + /** + * @param options + * options that govern call graph construction + * @param cha + * governing class hierarchy + * @param cl + * classloader that can find WALA resources + * @param scope + * representation of the analysis scope + * @param dmd + * deployment descriptor abstraction + * @param warnings + * an object which tracks analysis warnings + * @return a 0-1-CFA Call Graph Builder augmented with extra logic for + * containers + */ + public static CFABuilder makeZeroOneContainerCFABuilder(AnalysisOptions options, ClassHierarchy cha, ClassLoader cl, + AnalysisScope scope, DeploymentMetaData dmd, WarningSet warnings) { + + com.ibm.wala.ipa.callgraph.impl.Util.addDefaultSelectors(options, cha, warnings); + addDefaultJ2EEBypassLogic(options, scope, cl, cha); + ContextSelector appSelector = null; + SSAContextInterpreter appInterpreter = null; + if (dmd != null) { + ReceiverTypeInferenceCache typeInference = new ReceiverTypeInferenceCache(cha, options, warnings); + addJ2EEBypassLogic(options, scope, dmd, cha, typeInference, warnings); + appSelector = new J2EEContextSelector(typeInference, warnings); + appInterpreter = new CommandInterpreter(cha, warnings); + } + + return new ZeroOneContainerCFABuilder(cha, warnings, options, appSelector, appInterpreter, options.getReflectionSpec()); + } + + public static void addJ2EEBypassLogic(AnalysisOptions options, AnalysisScope scope, DeploymentMetaData dmd, ClassHierarchy cha, + ReceiverTypeInferenceCache typeInference, WarningSet warn) { + + MethodTargetSelector ms = new J2EEMethodTargetSelector(scope, options.getMethodTargetSelector(), dmd, cha, typeInference, warn); + options.setSelector(ms); + + ClassTargetSelector cs = new J2EEClassTargetSelector(options.getClassTargetSelector(), dmd, cha, cha.getLoader(scope + .getLoader(Atom.findOrCreateUnicodeAtom("Synthetic")))); + options.setSelector(cs); + } + + /** + * @param bean + * @param cha + * governing class hierarchy + * @return the Set of CMR fields for this bean, including inherited CMRs + */ + public static Set getCMRFields(BeanMetaData bean, DeploymentMetaData dmd, ClassHierarchy cha) { + Set result = HashSetFactory.make(5); + TypeReference T = bean.getEJBClass(); + while (T != null) { + BeanMetaData B = dmd.getBeanMetaData(T); + if (B != null) { + result.addAll(B.getCMRFields()); + } + IClass klass = cha.lookupClass(T); + if (Assertions.verifyAssertions) { + Assertions._assert(klass != null); + } + try { + IClass superKlass = klass.getSuperclass(); + T = (superKlass == null) ? null : superKlass.getReference(); + } catch (ClassHierarchyException e) { + Assertions.UNREACHABLE(); + } + } + return result; + } + + private static final String benignExtSpec = "benignext.xml"; + + public static void addDefaultJ2EEBypassLogic(AnalysisOptions options, AnalysisScope scope, ClassLoader cl, ClassHierarchy cha) { + com.ibm.wala.ipa.callgraph.impl.Util.addDefaultBypassLogic(options, scope, cl, cha); + com.ibm.wala.ipa.callgraph.impl.Util.addBypassLogic(options, scope, cl, benignExtSpec, cha); + } + +} diff --git a/com.ibm.wala.j2ee/src/com/ibm/wala/model/javax/servlet/RequestDispatcher.java b/com.ibm.wala.j2ee/src/com/ibm/wala/model/javax/servlet/RequestDispatcher.java new file mode 100644 index 000000000..a82b9f58b --- /dev/null +++ b/com.ibm.wala.j2ee/src/com/ibm/wala/model/javax/servlet/RequestDispatcher.java @@ -0,0 +1,15 @@ +package com.ibm.wala.model.javax.servlet; + + +class RequestDispatcher implements javax.servlet.RequestDispatcher { + + public void forward(javax.servlet.ServletRequest request, javax.servlet.ServletResponse response) { + + } + + public void include(javax.servlet.ServletRequest request, javax.servlet.ServletResponse response) { + + } + +} + diff --git a/com.ibm.wala.j2ee/src/com/ibm/wala/model/javax/servlet/ServletConfig.java b/com.ibm.wala.j2ee/src/com/ibm/wala/model/javax/servlet/ServletConfig.java new file mode 100644 index 000000000..71d9296e3 --- /dev/null +++ b/com.ibm.wala.j2ee/src/com/ibm/wala/model/javax/servlet/ServletConfig.java @@ -0,0 +1,48 @@ +/* + * Created on Mar 3, 2004 + * + * To change the template for this generated file go to + * Window>Preferences>Java>Code Generation>Code and Comments + */ +package com.ibm.wala.model.javax.servlet; + +import java.util.Enumeration; +import java.util.Vector; + +/** + * @author sfink + * + */ +public class ServletConfig implements javax.servlet.ServletConfig { + + /* (non-Javadoc) + * @see javax.servlet.ServletConfig#getServletName() + */ + public String getServletName() { + return "some name"; + } + + /* (non-Javadoc) + * @see javax.servlet.ServletConfig#getServletContext() + */ + public javax.servlet.ServletContext getServletContext() { + return com.ibm.wala.model.javax.servlet.ServletContext.getModelInstance(); + } + + /* (non-Javadoc) + * @see javax.servlet.ServletConfig#getInitParameter(java.lang.String) + */ + public String getInitParameter(String arg0) { + return new String("init parameter"); + } + + /* (non-Javadoc) + * @see javax.servlet.ServletConfig#getInitParameterNames() + */ + public Enumeration getInitParameterNames() { + Vector v = new Vector(); + v.add("a String"); + return v.elements(); + } + +} diff --git a/com.ibm.wala.j2ee/src/com/ibm/wala/model/javax/servlet/ServletContext.java b/com.ibm.wala.j2ee/src/com/ibm/wala/model/javax/servlet/ServletContext.java new file mode 100644 index 000000000..de3764bbe --- /dev/null +++ b/com.ibm.wala.j2ee/src/com/ibm/wala/model/javax/servlet/ServletContext.java @@ -0,0 +1,131 @@ +package com.ibm.wala.model.javax.servlet; + +import javax.servlet.Servlet; + +import com.ibm.wala.model.SyntheticFactory; + +public class ServletContext implements javax.servlet.ServletContext { + + private static ServletContext singleton = new ServletContext(); + + public static javax.servlet.ServletContext getModelInstance() { + return singleton; + } + + private static java.util.Hashtable values = new java.util.Hashtable(); + + public Object getAttribute(String name) { + if (name.length() > 5) { // random condition. + return values.get(name); + } else { + return SyntheticFactory.getObject(); + } + } + + public java.util.Enumeration getAttributeNames() { + return values.keys(); + } + + public javax.servlet.ServletContext getContext(String uripath) { + return singleton; + } + + public String getInitParameter(String name) { + return null; + } + + @SuppressWarnings("unchecked") + public java.util.Enumeration getInitParameterNames() { + return new java.util.Enumeration() { + public boolean hasMoreElements() { + return false; + } + + public Object nextElement() { + return null; + } + }; + } + + public int getMajorVersion() { + return 2; + } + + public String getMimeType(String file) { + return null; + } + + public int getMinorVersion() { + return 3; + } + + public javax.servlet.RequestDispatcher getNamedDispatcher(String name) { + return new RequestDispatcher(); + } + + public String getRealPath(String path) { + return path; + } + + public javax.servlet.RequestDispatcher getRequestDispatcher(String path) { + return new RequestDispatcher(); + } + + public java.net.URL getResource(String path) { + try { + return new java.net.URL(path); + } catch (java.net.MalformedURLException e) { + return null; + } + } + + public java.io.InputStream getResourceAsStream(String path) { + return null; + } + + public java.util.Set getResourcePaths(String path) { + return java.util.Collections.emptySet(); + } + + public java.lang.String getServerInfo() { + return "WALA J2EE model"; + } + + public Servlet getServlet(java.lang.String name) { + return null; + } + + public String getServletContextName() { + return "WALA J2EE model ServletContext"; + } + + @SuppressWarnings("unchecked") + public java.util.Enumeration getServletNames() { + return null; + } + + @SuppressWarnings("unchecked") + public java.util.Enumeration getServlets() { + return null; + } + + public void log(Exception exception, String msg) { + + } + + public void log(String msg) { + + } + + public void log(String message, Throwable throwable) { + + } + + public void removeAttribute(String name) { + values.remove(name); + } + + public void setAttribute(String name, Object object) { + values.put(name, object); + } +} diff --git a/com.ibm.wala.j2ee/src/com/ibm/wala/model/javax/servlet/ServletRequest.java b/com.ibm.wala.j2ee/src/com/ibm/wala/model/javax/servlet/ServletRequest.java new file mode 100644 index 000000000..560afe806 --- /dev/null +++ b/com.ibm.wala.j2ee/src/com/ibm/wala/model/javax/servlet/ServletRequest.java @@ -0,0 +1,133 @@ +package com.ibm.wala.model.javax.servlet; + +import javax.servlet.ServletInputStream; + +import com.ibm.wala.model.SyntheticFactory; + +public class ServletRequest implements javax.servlet.ServletRequest { + private final java.util.Hashtable values = new java.util.Hashtable(); + private final java.util.Hashtable parameters = new java.util.Hashtable(); + private String encoding = "iso88591-1"; + + public ServletRequest() { + parameters.put("key", "value"); + } + + public Object getAttribute(String name) { + if (name.length() > 5) { // random condition. + return values.get(name); + } else { + return SyntheticFactory.getObject(); + } + } + + public java.util.Enumeration getAttributeNames() { + return values.keys(); + } + + public java.lang.String getCharacterEncoding() { + return encoding; + } + + public int getContentLength() { + return -1; + } + + public java.lang.String getContentType() { + return null; + } + + public javax.servlet.ServletInputStream getInputStream() { + return new ServletInputStream() { + public int read() throws java.io.IOException { + return 0; + } + }; + } + + public java.util.Locale getLocale() { + return java.util.Locale.getDefault(); + } + + @SuppressWarnings("unchecked") + public java.util.Enumeration getLocales() { + return new java.util.Enumeration() { + private boolean done = false; + public boolean hasMoreElements() { + return !done; + } + public Object nextElement() { + done = true; + return getLocale(); + } + }; + } + + public String getParameter(String name) { + return parameters.get(name); + } + + public java.util.Map getParameterMap() { + return parameters; + } + + public java.util.Enumeration getParameterNames() { + return parameters.keys(); + } + + public String[] getParameterValues(String name) { + return new String[] {parameters.get(name)}; + } + + public java.lang.String getProtocol() { + return "HTTP/1.1"; + } + + public java.io.BufferedReader getReader() { + return null; + } + + public String getRealPath(String path) { + return path; + } + + public String getRemoteAddr() { + return "0.0.0.0"; + } + + public String getRemoteHost() { + return "remotehost"; + } + + public javax.servlet.RequestDispatcher getRequestDispatcher(String path) { + return new RequestDispatcher(); + } + + public String getScheme() { + return "http"; + } + + public String getServerName() { + return "localhost.localdomain"; + } + + public int getServerPort() { + return 80; + } + + public boolean isSecure() { + return false; + } + + public void removeAttribute(String name) { + values.remove(name); + } + + public void setAttribute(String name, Object o) { + values.put(name, o); + } + + public void setCharacterEncoding(String env) { + encoding = env; + } +} diff --git a/com.ibm.wala.j2ee/src/com/ibm/wala/model/javax/servlet/ServletResponse.java b/com.ibm.wala.j2ee/src/com/ibm/wala/model/javax/servlet/ServletResponse.java new file mode 100644 index 000000000..2a7678998 --- /dev/null +++ b/com.ibm.wala.j2ee/src/com/ibm/wala/model/javax/servlet/ServletResponse.java @@ -0,0 +1,68 @@ +package com.ibm.wala.model.javax.servlet; + +import javax.servlet.*; + +public class ServletResponse implements javax.servlet.ServletResponse { + private java.util.Locale locale = java.util.Locale.getDefault();; + + private int bufferSize = -1; + + private final ServletOutputStream out = new ServletOutputStream() { + public void write (int b) throws java.io.IOException { + + } + }; + + public void flushBuffer() { + + } + + public int getBufferSize() { + return bufferSize; + } + + public String getCharacterEncoding() { + return "iso8859-1"; + } + + public java.util.Locale getLocale() { + return locale; + } + + public ServletOutputStream getOutputStream() { + return out; + } + + public java.io.PrintWriter getWriter() { + return new java.io.PrintWriter( out ); + } + + public boolean isCommitted() { + return false; + } + + public void reset() { + + } + + public void resetBuffer() { + + } + + public void setBufferSize(int size) { + bufferSize = size; + } + + public void setContentLength(int len) { + + } + + public void setContentType(java.lang.String type) { + + } + + public void setLocale(java.util.Locale loc) { + locale = loc; + } +} + diff --git a/com.ibm.wala.j2ee/src/com/ibm/wala/model/javax/servlet/http/HttpServletRequest.java b/com.ibm.wala.j2ee/src/com/ibm/wala/model/javax/servlet/http/HttpServletRequest.java new file mode 100644 index 000000000..ecf2b2420 --- /dev/null +++ b/com.ibm.wala.j2ee/src/com/ibm/wala/model/javax/servlet/http/HttpServletRequest.java @@ -0,0 +1,114 @@ +package com.ibm.wala.model.javax.servlet.http; + +import javax.servlet.http.Cookie; + +public class HttpServletRequest + extends com.ibm.wala.model.javax.servlet.ServletRequest + implements javax.servlet.http.HttpServletRequest { + private final java.util.Hashtable headers = new java.util.Hashtable(); + + public HttpServletRequest() { + headers.put("header", "value"); + headers.get("header"); + } + + public String getAuthType() { + return "none"; + } + + public String getContextPath() { + return "this/that/the/other"; + } + + public Cookie[] getCookies() { + return null; + } + + public long getDateHeader(String name) { + return 0; + } + + public String getHeader(String name) { + return headers.get(name); + } + + public java.util.Enumeration getHeaderNames() { + return headers.keys(); + } + + public java.util.Enumeration getHeaders(String name) { + return headers.elements(); + } + + public int getIntHeader(String name) { + return (new Integer(getHeader(name))).intValue(); + } + + public String getMethod() { + return "GET"; + } + + public java.lang.String getPathInfo() { + return null; + } + + public String getPathTranslated() { + return "path"; + } + + public String getQueryString() { + return "?stuff"; + } + + public String getRemoteUser() { + return null; + } + + public String getRequestedSessionId() { + return "SESSION1"; + } + + public String getRequestURI() { + return "this/that/the/other"; + } + + public StringBuffer getRequestURL() { + return new StringBuffer(getRequestURI()); + } + + public String getServletPath() { + return "this/that/the/other"; + } + + public javax.servlet.http.HttpSession getSession() { + return HttpSession.getModelInstance(); + } + + public javax.servlet.http.HttpSession getSession(boolean create) { + return HttpSession.getModelInstance(); + } + + public java.security.Principal getUserPrincipal() { + return null; + } + + public boolean isRequestedSessionIdFromCookie() { + return true; + } + + public boolean isRequestedSessionIdFromUrl() { + return true; + } + + public boolean isRequestedSessionIdFromURL() { + return true; + } + + public boolean isRequestedSessionIdValid() { + return true; + } + + public boolean isUserInRole(String role) { + return true; + } +} diff --git a/com.ibm.wala.j2ee/src/com/ibm/wala/model/javax/servlet/http/HttpServletResponse.java b/com.ibm.wala.j2ee/src/com/ibm/wala/model/javax/servlet/http/HttpServletResponse.java new file mode 100644 index 000000000..e20b4c1c5 --- /dev/null +++ b/com.ibm.wala.j2ee/src/com/ibm/wala/model/javax/servlet/http/HttpServletResponse.java @@ -0,0 +1,79 @@ +package com.ibm.wala.model.javax.servlet.http; + +import javax.servlet.http.Cookie; + +public class HttpServletResponse + extends com.ibm.wala.model.javax.servlet.ServletResponse + implements javax.servlet.http.HttpServletResponse { + @SuppressWarnings("unchecked") + private final java.util.Hashtable headers = new java.util.Hashtable(); + + public void addCookie(Cookie cookie) { + + } + + public void addDateHeader(String name, long date) { + headers.put(name, new java.util.Date(date)); + } + + public void addHeader(String name, String value) { + headers.put(name, value); + } + + public void addIntHeader(java.lang.String name, int value) { + headers.put(name, new Integer(value)); + } + + public boolean containsHeader(String name) { + return headers.containsKey(name); + } + + public String encodeRedirectUrl(String url) { + return url; + } + + public String encodeRedirectURL(String url) { + return url; + } + + public String encodeUrl(String url) { + return url; + } + + public String encodeURL(String url) { + return url; + } + + public void sendError(int sc) { + + } + + public void sendError(int sc, String msg) { + + } + + public void sendRedirect(String location) { + + } + + public void setDateHeader(String name, long date) { + headers.put(name, new java.util.Date(date)); + } + + public void setHeader(String name, String value) { + headers.put(name, value); + } + + public void setIntHeader(String name, int value) { + headers.put(name, new Integer(value)); + } + + public void setStatus(int sc) { + + } + + public void setStatus(int sc, String sm) { + + } + +} diff --git a/com.ibm.wala.j2ee/src/com/ibm/wala/model/javax/servlet/http/HttpSession.java b/com.ibm.wala.j2ee/src/com/ibm/wala/model/javax/servlet/http/HttpSession.java new file mode 100644 index 000000000..c99f90ab6 --- /dev/null +++ b/com.ibm.wala.j2ee/src/com/ibm/wala/model/javax/servlet/http/HttpSession.java @@ -0,0 +1,179 @@ +/* + * Created on Sep 19, 2003 + * + * To change the template for this generated file go to + * Window>Preferences>Java>Code Generation>Code and Comments + */ +package com.ibm.wala.model.javax.servlet.http; + +import java.util.Enumeration; +import java.util.Hashtable; + +import javax.servlet.ServletContext; +import javax.servlet.http.HttpSessionContext; + +import com.ibm.wala.model.SyntheticFactory; + +/** + * @author sfink + * + * TODO: finish this model + */ +public class HttpSession implements javax.servlet.http.HttpSession { + + private static final HttpSession singleton = new HttpSession(); + + public static javax.servlet.http.HttpSession getModelInstance() { + return singleton; + } + + private Hashtable attributes = new Hashtable(); + private Hashtable values = new Hashtable(); + + /** + * + */ + public HttpSession() { + super(); + // TODO Auto-generated constructor stub + } + + /* (non-Javadoc) + * @see javax.servlet.http.HttpSession#getCreationTime() + */ + public long getCreationTime() { + // TODO Auto-generated method stub + return 0; + } + + /* (non-Javadoc) + * @see javax.servlet.http.HttpSession#getId() + */ + public String getId() { + // TODO Auto-generated method stub + return null; + } + + /* (non-Javadoc) + * @see javax.servlet.http.HttpSession#getLastAccessedTime() + */ + public long getLastAccessedTime() { + // TODO Auto-generated method stub + return 0; + } + + /* (non-Javadoc) + * @see javax.servlet.http.HttpSession#getServletContext() + */ + public ServletContext getServletContext() { + // TODO Auto-generated method stub + return null; + } + + /* (non-Javadoc) + * @see javax.servlet.http.HttpSession#setMaxInactiveInterval(int) + */ + public void setMaxInactiveInterval(int arg0) { + // TODO Auto-generated method stub + + } + + /* (non-Javadoc) + * @see javax.servlet.http.HttpSession#getMaxInactiveInterval() + */ + public int getMaxInactiveInterval() { + // TODO Auto-generated method stub + return 0; + } + + /* (non-Javadoc) + * @see javax.servlet.http.HttpSession#getSessionContext() + */ + public HttpSessionContext getSessionContext() { + // TODO Auto-generated method stub + return null; + } + + /* (non-Javadoc) + * @see javax.servlet.http.HttpSession#getAttribute(java.lang.String) + */ + public Object getAttribute(String arg0) { + if (arg0.length() > 5) { // random condition. + return attributes.get(arg0); + } else { + return SyntheticFactory.getObject(); + } + } + + /* (non-Javadoc) + * @see javax.servlet.http.HttpSession#getValue(java.lang.String) + */ + public Object getValue(String arg0) { + if (arg0.length() > 5) { // random condition. + return values.get( arg0 ); + } else { + return SyntheticFactory.getObject(); + } + } + + /* (non-Javadoc) + * @see javax.servlet.http.HttpSession#getAttributeNames() + */ + public Enumeration getAttributeNames() { + return attributes.keys(); + } + + /* (non-Javadoc) + * @see javax.servlet.http.HttpSession#getValueNames() + */ + public String[] getValueNames() { + return new String[0]; + } + + /* (non-Javadoc) + * @see javax.servlet.http.HttpSession#setAttribute(java.lang.String, java.lang.Object) + */ + public void setAttribute(String arg0, Object arg1) { + attributes.put(arg0, arg1); + } + + /* (non-Javadoc) + * @see javax.servlet.http.HttpSession#putValue(java.lang.String, java.lang.Object) + */ + public void putValue(String arg0, Object arg1) { + values.put(arg0, arg1); + } + + /* (non-Javadoc) + * @see javax.servlet.http.HttpSession#removeAttribute(java.lang.String) + */ + public void removeAttribute(String arg0) { + // TODO Auto-generated method stub + + } + + /* (non-Javadoc) + * @see javax.servlet.http.HttpSession#removeValue(java.lang.String) + */ + public void removeValue(String arg0) { + // TODO Auto-generated method stub + + } + + /* (non-Javadoc) + * @see javax.servlet.http.HttpSession#invalidate() + */ + public void invalidate() { + // TODO Auto-generated method stub + + } + + /* (non-Javadoc) + * @see javax.servlet.http.HttpSession#isNew() + */ + public boolean isNew() { + // TODO Auto-generated method stub + return false; + } + +} diff --git a/com.ibm.wala.shrike/.classpath b/com.ibm.wala.shrike/.classpath new file mode 100644 index 000000000..751c8f2e5 --- /dev/null +++ b/com.ibm.wala.shrike/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/com.ibm.wala.shrike/.cvsignore b/com.ibm.wala.shrike/.cvsignore new file mode 100644 index 000000000..f7b0f017f --- /dev/null +++ b/com.ibm.wala.shrike/.cvsignore @@ -0,0 +1,4 @@ +build +shrike.jar +domo-trace.txt* +com.ibm.shrike_*.jar diff --git a/com.ibm.wala.shrike/.project b/com.ibm.wala.shrike/.project new file mode 100644 index 000000000..92e255dc0 --- /dev/null +++ b/com.ibm.wala.shrike/.project @@ -0,0 +1,28 @@ + + + com.ibm.wala.shrike + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/com.ibm.wala.shrike/.settings/org.eclipse.jdt.core.prefs b/com.ibm.wala.shrike/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 000000000..15164c67a --- /dev/null +++ b/com.ibm.wala.shrike/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,12 @@ +#Mon Oct 02 09:00:09 EDT 2006 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5 +org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve +org.eclipse.jdt.core.compiler.compliance=1.5 +org.eclipse.jdt.core.compiler.debug.lineNumber=generate +org.eclipse.jdt.core.compiler.debug.localVariable=generate +org.eclipse.jdt.core.compiler.debug.sourceFile=generate +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.source=1.5 diff --git a/com.ibm.wala.shrike/.settings/org.eclipse.jdt.ui.prefs b/com.ibm.wala.shrike/.settings/org.eclipse.jdt.ui.prefs new file mode 100644 index 000000000..c3916e640 --- /dev/null +++ b/com.ibm.wala.shrike/.settings/org.eclipse.jdt.ui.prefs @@ -0,0 +1,3 @@ +#Mon Oct 02 09:00:09 EDT 2006 +eclipse.preferences.version=1 +internal.default.compliance=default diff --git a/com.ibm.wala.shrike/META-INF/MANIFEST.MF b/com.ibm.wala.shrike/META-INF/MANIFEST.MF new file mode 100644 index 000000000..8d516a87d --- /dev/null +++ b/com.ibm.wala.shrike/META-INF/MANIFEST.MF @@ -0,0 +1,18 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Shrike Bytecode Manipulation Library +Bundle-SymbolicName: com.ibm.wala.shrike +Bundle-Version: 1.0.0 +Bundle-Vendor: WALA +Bundle-Localization: plugin +Eclipse-LazyStart: true +Export-Package: com.ibm.wala.shrike.bench, + com.ibm.wala.shrike.copywriter, + com.ibm.wala.shrike.tools, + com.ibm.wala.shrikeBT, + com.ibm.wala.shrikeBT.analysis, + com.ibm.wala.shrikeBT.info, + com.ibm.wala.shrikeBT.shrikeCT, + com.ibm.wala.shrikeBT.shrikeCT.tools, + com.ibm.wala.shrikeBT.tools, + com.ibm.wala.shrikeCT diff --git a/com.ibm.wala.shrike/build.properties b/com.ibm.wala.shrike/build.properties new file mode 100644 index 000000000..30d8c0866 --- /dev/null +++ b/com.ibm.wala.shrike/build.properties @@ -0,0 +1,5 @@ +bin.includes = META-INF/,\ + . +jars.compile.order = . +source.. = src/ +output.. = bin/ diff --git a/com.ibm.wala.shrike/build.xml b/com.ibm.wala.shrike/build.xml new file mode 100644 index 000000000..bd0f36937 --- /dev/null +++ b/com.ibm.wala.shrike/build.xml @@ -0,0 +1,170 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/com.ibm.wala.shrike/com.ibm.wala.shrike/.classpath b/com.ibm.wala.shrike/com.ibm.wala.shrike/.classpath new file mode 100644 index 000000000..751c8f2e5 --- /dev/null +++ b/com.ibm.wala.shrike/com.ibm.wala.shrike/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/com.ibm.wala.shrike/com.ibm.wala.shrike/.cvsignore b/com.ibm.wala.shrike/com.ibm.wala.shrike/.cvsignore new file mode 100644 index 000000000..f7b0f017f --- /dev/null +++ b/com.ibm.wala.shrike/com.ibm.wala.shrike/.cvsignore @@ -0,0 +1,4 @@ +build +shrike.jar +domo-trace.txt* +com.ibm.shrike_*.jar diff --git a/com.ibm.wala.shrike/com.ibm.wala.shrike/.project b/com.ibm.wala.shrike/com.ibm.wala.shrike/.project new file mode 100644 index 000000000..92e255dc0 --- /dev/null +++ b/com.ibm.wala.shrike/com.ibm.wala.shrike/.project @@ -0,0 +1,28 @@ + + + com.ibm.wala.shrike + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/com.ibm.wala.shrike/com.ibm.wala.shrike/.settings/org.eclipse.jdt.core.prefs b/com.ibm.wala.shrike/com.ibm.wala.shrike/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 000000000..15164c67a --- /dev/null +++ b/com.ibm.wala.shrike/com.ibm.wala.shrike/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,12 @@ +#Mon Oct 02 09:00:09 EDT 2006 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5 +org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve +org.eclipse.jdt.core.compiler.compliance=1.5 +org.eclipse.jdt.core.compiler.debug.lineNumber=generate +org.eclipse.jdt.core.compiler.debug.localVariable=generate +org.eclipse.jdt.core.compiler.debug.sourceFile=generate +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.source=1.5 diff --git a/com.ibm.wala.shrike/com.ibm.wala.shrike/.settings/org.eclipse.jdt.ui.prefs b/com.ibm.wala.shrike/com.ibm.wala.shrike/.settings/org.eclipse.jdt.ui.prefs new file mode 100644 index 000000000..c3916e640 --- /dev/null +++ b/com.ibm.wala.shrike/com.ibm.wala.shrike/.settings/org.eclipse.jdt.ui.prefs @@ -0,0 +1,3 @@ +#Mon Oct 02 09:00:09 EDT 2006 +eclipse.preferences.version=1 +internal.default.compliance=default diff --git a/com.ibm.wala.shrike/com.ibm.wala.shrike/META-INF/MANIFEST.MF b/com.ibm.wala.shrike/com.ibm.wala.shrike/META-INF/MANIFEST.MF new file mode 100644 index 000000000..8d516a87d --- /dev/null +++ b/com.ibm.wala.shrike/com.ibm.wala.shrike/META-INF/MANIFEST.MF @@ -0,0 +1,18 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Shrike Bytecode Manipulation Library +Bundle-SymbolicName: com.ibm.wala.shrike +Bundle-Version: 1.0.0 +Bundle-Vendor: WALA +Bundle-Localization: plugin +Eclipse-LazyStart: true +Export-Package: com.ibm.wala.shrike.bench, + com.ibm.wala.shrike.copywriter, + com.ibm.wala.shrike.tools, + com.ibm.wala.shrikeBT, + com.ibm.wala.shrikeBT.analysis, + com.ibm.wala.shrikeBT.info, + com.ibm.wala.shrikeBT.shrikeCT, + com.ibm.wala.shrikeBT.shrikeCT.tools, + com.ibm.wala.shrikeBT.tools, + com.ibm.wala.shrikeCT diff --git a/com.ibm.wala.shrike/com.ibm.wala.shrike/build.properties b/com.ibm.wala.shrike/com.ibm.wala.shrike/build.properties new file mode 100644 index 000000000..30d8c0866 --- /dev/null +++ b/com.ibm.wala.shrike/com.ibm.wala.shrike/build.properties @@ -0,0 +1,5 @@ +bin.includes = META-INF/,\ + . +jars.compile.order = . +source.. = src/ +output.. = bin/ diff --git a/com.ibm.wala.shrike/com.ibm.wala.shrike/build.xml b/com.ibm.wala.shrike/com.ibm.wala.shrike/build.xml new file mode 100644 index 000000000..bd0f36937 --- /dev/null +++ b/com.ibm.wala.shrike/com.ibm.wala.shrike/build.xml @@ -0,0 +1,170 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/com.ibm.wala.shrike/com.ibm.wala.shrike/exportPlugin.xml b/com.ibm.wala.shrike/com.ibm.wala.shrike/exportPlugin.xml new file mode 100644 index 000000000..234124335 --- /dev/null +++ b/com.ibm.wala.shrike/com.ibm.wala.shrike/exportPlugin.xml @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/com.ibm.wala.shrike/com.ibm.wala.shrike/javaCompiler...args b/com.ibm.wala.shrike/com.ibm.wala.shrike/javaCompiler...args new file mode 100644 index 000000000..051894b39 --- /dev/null +++ b/com.ibm.wala.shrike/com.ibm.wala.shrike/javaCompiler...args @@ -0,0 +1,14 @@ +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.core.runtime_3.2.0.v20060603.jar[~org/eclipse/core/internal/preferences/legacy/*;~org/eclipse/core/internal/runtime/*;+org/eclipse/core/runtime/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.osgi_3.2.0.v20060601.jar[+org/eclipse/osgi/event/*;+org/eclipse/osgi/framework/console/*;+org/eclipse/osgi/framework/eventmgr/*;+org/eclipse/osgi/framework/log/*;+org/eclipse/osgi/service/datalocation/*;+org/eclipse/osgi/service/debug/*;+org/eclipse/osgi/service/environment/*;+org/eclipse/osgi/service/localization/*;+org/eclipse/osgi/service/pluginconversion/*;+org/eclipse/osgi/service/resolver/*;+org/eclipse/osgi/service/runnable/*;+org/eclipse/osgi/service/urlconversion/*;+org/eclipse/osgi/storagemanager/*;+org/eclipse/osgi/util/*;+org/osgi/framework/*;+org/osgi/service/condpermadmin/*;+org/osgi/service/packageadmin/*;+org/osgi/service/permissionadmin/*;+org/osgi/service/startlevel/*;+org/osgi/service/url/*;+org/osgi/util/tracker/*;~org/eclipse/core/runtime/adaptor/*;~org/eclipse/core/runtime/internal/adaptor/*;~org/eclipse/core/runtime/internal/stats/*;~org/eclipse/osgi/baseadaptor/*;~org/eclipse/osgi/baseadaptor/bundlefile/*;~org/eclipse/osgi/baseadaptor/hooks/*;~org/eclipse/osgi/baseadaptor/loader/*;~org/eclipse/osgi/framework/adaptor/*;~org/eclipse/osgi/framework/debug/*;~org/eclipse/osgi/framework/internal/core/*;~org/eclipse/osgi/framework/internal/protocol/*;~org/eclipse/osgi/framework/internal/protocol/bundleentry/*;~org/eclipse/osgi/framework/internal/protocol/bundleresource/*;~org/eclipse/osgi/framework/internal/protocol/reference/*;~org/eclipse/osgi/framework/internal/reliablefile/*;~org/eclipse/osgi/framework/launcher/*;~org/eclipse/osgi/framework/util/*;~org/eclipse/osgi/internal/baseadaptor/*;~org/eclipse/osgi/internal/module/*;~org/eclipse/osgi/internal/profile/*;~org/eclipse/osgi/internal/resolver/*;~org/eclipse/osgi/internal/verifier/*;~org/eclipse/osgi/internal/provisional/verifier/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.equinox.common_3.2.0.v20060603.jar[~org/eclipse/core/internal/runtime/*;~org/eclipse/core/internal/boot/*;+org/eclipse/core/runtime/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.core.jobs_3.2.0.v20060603.jar[~org/eclipse/core/internal/jobs/*;+org/eclipse/core/runtime/jobs/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.core.runtime.compatibility.registry_3.2.0.v20060603/runtime_registry_compatibility.jar[~org/eclipse/core/internal/registry/*;~org/eclipse/core/internal/registry/osgi/*;~org/eclipse/core/internal/registry/spi/*;+org/eclipse/core/runtime/*;+org/eclipse/core/runtime/dynamichelpers/*;+org/eclipse/core/runtime/spi/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.core.runtime.compatibility.registry_3.2.0.v20060603[~org/eclipse/core/internal/registry/*;~org/eclipse/core/internal/registry/osgi/*;~org/eclipse/core/internal/registry/spi/*;+org/eclipse/core/runtime/*;+org/eclipse/core/runtime/dynamichelpers/*;+org/eclipse/core/runtime/spi/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.equinox.registry_3.2.0.v20060601.jar[~org/eclipse/core/internal/registry/*;~org/eclipse/core/internal/registry/osgi/*;~org/eclipse/core/internal/registry/spi/*;+org/eclipse/core/runtime/*;+org/eclipse/core/runtime/dynamichelpers/*;+org/eclipse/core/runtime/spi/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.apache.xerces_2.8.0.v200606131651/resolver.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.apache.xerces_2.8.0.v200606131651/xercesImpl.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.apache.xerces_2.8.0.v200606131651/xml-apis.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.equinox.preferences_3.2.0.v20060601.jar[~org/eclipse/core/internal/preferences/*;~org/eclipse/core/internal/preferences/exchange/*;+org/eclipse/core/runtime/preferences/*;+org/osgi/service/prefs/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.core.runtime.compatibility.registry_3.2.0.v20060603/@dot[~org/eclipse/core/internal/registry/*;~org/eclipse/core/internal/registry/osgi/*;~org/eclipse/core/internal/registry/spi/*;+org/eclipse/core/runtime/*;+org/eclipse/core/runtime/dynamichelpers/*;+org/eclipse/core/runtime/spi/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.core.contenttype_3.2.0.v20060603.jar[~org/eclipse/core/internal/content/*;+org/eclipse/core/runtime/content/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.core.runtime.compatibility.auth_3.2.0.v20060601.jar[?**/*] diff --git a/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrike/bench/AddBytecodeDebug.java b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrike/bench/AddBytecodeDebug.java new file mode 100644 index 000000000..4b07b5f97 --- /dev/null +++ b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrike/bench/AddBytecodeDebug.java @@ -0,0 +1,103 @@ +/******************************************************************************* + * 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.FileWriter; +import java.io.Writer; + +import com.ibm.wala.shrikeBT.DupInstruction; +import com.ibm.wala.shrikeBT.ExceptionHandler; +import com.ibm.wala.shrikeBT.MethodData; +import com.ibm.wala.shrikeBT.MethodEditor; +import com.ibm.wala.shrikeBT.Util; +import com.ibm.wala.shrikeBT.MethodEditor.Output; +import com.ibm.wala.shrikeBT.shrikeCT.ClassInstrumenter; +import com.ibm.wala.shrikeBT.shrikeCT.OfflineInstrumenter; +import com.ibm.wala.shrikeCT.ClassWriter; + +/** + * This is a demo class. + * + * Class files are taken as input arguments (or if there are none, from standard + * input). The methods in those files are instrumented: we insert a + * System.err.println() at ever method call, and a System.err.println() at every + * method entry. + * + * In Unix, I run it like this: java -cp ~/dev/shrike/shrike + * com.ibm.wala.shrikeBT.shrikeCT.tools.Bench test.jar -o output.jar + * + * The instrumented classes are placed in the directory "output" under the + * current directory. Disassembled code is written to the file "report" under + * the current directory. + * + * @author Rob O' Callahan + */ +public class AddBytecodeDebug { + private static OfflineInstrumenter instrumenter; + + public static void main(String[] args) throws Exception { + for (int i = 0; i < 1; i++) { + instrumenter = new OfflineInstrumenter(); + + Writer w = new BufferedWriter(new FileWriter("report", false)); + + args = instrumenter.parseStandardArgs(args); + instrumenter.setPassUnmodifiedClasses(true); + instrumenter.beginTraversal(); + ClassInstrumenter ci; + while ((ci = instrumenter.nextClass()) != null) { + doClass(ci, w); + } + instrumenter.close(); + } + } + + private static void doClass(final ClassInstrumenter ci, Writer w) throws Exception { + final String className = ci.getReader().getName(); + w.write("Class: " + className + "\n"); + w.flush(); + + ci.enableFakeLineNumbers(10000); + + for (int m = 0; m < ci.getReader().getMethodCount(); m++) { + MethodData d = ci.visitMethod(m); + if (d != null) { + d.setHasChanged(); + + MethodEditor me = new MethodEditor(d); + me.beginPass(); + ExceptionHandler[][] handlers = me.getHandlers(); + boolean[] putDumperAt = new boolean[handlers.length]; + for (int i = 0; i < handlers.length; i++) { + for (int j = 0; j < handlers[i].length; j++) { + int offset = handlers[i][j].getHandler(); + if (!putDumperAt[offset]) { + putDumperAt[offset] = true; + me.insertBefore(offset, new MethodEditor.Patch() { + public void emitTo(Output w) { + w.emit(DupInstruction.make(0)); + w.emit(Util.makeInvoke(Throwable.class, "printStackTrace", new Class[0])); + } + }); + } + } + } + me.applyPatches(); + } + } + + if (ci.isChanged()) { + ClassWriter cw = ci.emitClass(); + instrumenter.outputModifiedClass(ci, cw); + } + } +} diff --git a/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrike/bench/Bench.java b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrike/bench/Bench.java new file mode 100644 index 000000000..d40c5ad25 --- /dev/null +++ b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrike/bench/Bench.java @@ -0,0 +1,191 @@ +/******************************************************************************* + * 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.FileWriter; +import java.io.PrintStream; +import java.io.Writer; + +import com.ibm.wala.shrikeBT.ConditionalBranchInstruction; +import com.ibm.wala.shrikeBT.ConstantInstruction; +import com.ibm.wala.shrikeBT.Constants; +import com.ibm.wala.shrikeBT.Disassembler; +import com.ibm.wala.shrikeBT.GetInstruction; +import com.ibm.wala.shrikeBT.Instruction; +import com.ibm.wala.shrikeBT.MethodData; +import com.ibm.wala.shrikeBT.MethodEditor; +import com.ibm.wala.shrikeBT.ReturnInstruction; +import com.ibm.wala.shrikeBT.ThrowInstruction; +import com.ibm.wala.shrikeBT.Util; +import com.ibm.wala.shrikeBT.MethodEditor.Output; +import com.ibm.wala.shrikeBT.analysis.Verifier; +import com.ibm.wala.shrikeBT.shrikeCT.CTDecoder; +import com.ibm.wala.shrikeBT.shrikeCT.ClassInstrumenter; +import com.ibm.wala.shrikeBT.shrikeCT.OfflineInstrumenter; +import com.ibm.wala.shrikeCT.ClassReader; +import com.ibm.wala.shrikeCT.ClassWriter; + +/** + * This is a demo class. + * + * Class files are taken as input arguments (or if there are none, from standard + * input). The methods in those files are instrumented: we insert a + * System.err.println() at ever method call, and a System.err.println() at every + * method entry. + * + * In Unix, I run it like this: java -cp ~/dev/shrike/shrike + * com.ibm.wala.shrikeBT.shrikeCT.tools.Bench test.jar -o output.jar + * + * The instrumented classes are placed in the directory "output" under the + * current directory. Disassembled code is written to the file "report" under + * the current directory. + */ +public class Bench { + private final static boolean disasm = true; + private final static boolean verify = true; + + private static OfflineInstrumenter instrumenter; + + private static boolean doEntry = true; + private static boolean doExit = false; + private static boolean doException = false; + + public static void main(String[] args) throws Exception { + for (int i = 0; i < 1; i++) { + instrumenter = new OfflineInstrumenter(); + + Writer w = new BufferedWriter(new FileWriter("report", false)); + + args = instrumenter.parseStandardArgs(args); + if (args.length > 0) { + if (args[0].equals("-doexit")) { + doExit = true; + } else if (args[0].equals("-doexception")) { + doExit = true; + doException = true; + } + } + instrumenter.setPassUnmodifiedClasses(true); + instrumenter.beginTraversal(); + ClassInstrumenter ci; + while ((ci = instrumenter.nextClass()) != null) { + doClass(ci, w); + } + instrumenter.close(); + } + } + + static final String fieldName = "_Bench_enable_trace"; + + // Keep these commonly used instructions around + static final Instruction getSysErr = Util.makeGet(System.class, "err"); + static final Instruction callPrintln = Util.makeInvoke(PrintStream.class, "println", new Class[] { String.class }); + + private static void doClass(final ClassInstrumenter ci, Writer w) throws Exception { + final String className = ci.getReader().getName(); + w.write("Class: " + className + "\n"); + w.flush(); + + for (int m = 0; m < ci.getReader().getMethodCount(); m++) { + MethodData d = ci.visitMethod(m); + + // d could be null, e.g., if the method is abstract or native + if (d != null) { + w.write("Instrumenting " + ci.getReader().getMethodName(m) + " " + ci.getReader().getMethodType(m) + ":\n"); + w.flush(); + + if (disasm) { + w.write("Initial ShrikeBT code:\n"); + (new Disassembler(d)).disassembleTo(w); + w.flush(); + } + + if (verify) { + Verifier v = new Verifier(d); + v.verify(); + } + + MethodEditor me = new MethodEditor(d); + me.beginPass(); + + if (doEntry) { + final String msg0 = "Entering call to " + Util.makeClass("L" + ci.getReader().getName() + ";") + "." + + ci.getReader().getMethodName(m); + final int noTraceLabel = me.allocateLabel(); + me.insertAtStart(new MethodEditor.Patch() { + public void emitTo(MethodEditor.Output w) { + w.emit(GetInstruction.make(Constants.TYPE_boolean, CTDecoder.convertClassToType(className), fieldName, true)); + w.emit(ConstantInstruction.make(0)); + w.emit(ConditionalBranchInstruction.make(Constants.TYPE_int, ConditionalBranchInstruction.Operator.EQ, noTraceLabel)); + w.emit(getSysErr); + w.emit(ConstantInstruction.makeString(msg0)); + w.emit(callPrintln); + w.emitLabel(noTraceLabel); + } + }); + } + if (doExit) { + final String msg0 = "Exiting call to " + Util.makeClass("L" + ci.getReader().getName() + ";") + "." + + ci.getReader().getMethodName(m); + Instruction[] instr = me.getInstructions(); + for (int i = 0; i < instr.length; i++) { + if (instr[i] instanceof ReturnInstruction) { + final int noTraceLabel = me.allocateLabel(); + me.insertBefore(i, new MethodEditor.Patch() { + public void emitTo(MethodEditor.Output w) { + w.emit(GetInstruction.make(Constants.TYPE_boolean, CTDecoder.convertClassToType(className), fieldName, true)); + w.emit(ConstantInstruction.make(0)); + w.emit(ConditionalBranchInstruction.make(Constants.TYPE_int, ConditionalBranchInstruction.Operator.EQ, noTraceLabel)); + w.emit(getSysErr); + w.emit(ConstantInstruction.makeString(msg0)); + w.emit(callPrintln); + w.emitLabel(noTraceLabel); + } + }); + } + } + } + if (doException) { + final String msg0 = "Exception exiting call to " + Util.makeClass("L" + ci.getReader().getName() + ";") + "." + + ci.getReader().getMethodName(m); + final int noTraceLabel = me.allocateLabel(); + me.addMethodExceptionHandler(null, new MethodEditor.Patch() { + public void emitTo(Output w) { + w.emit(GetInstruction.make(Constants.TYPE_boolean, CTDecoder.convertClassToType(className), fieldName, true)); + w.emit(ConstantInstruction.make(0)); + w.emit(ConditionalBranchInstruction.make(Constants.TYPE_int, ConditionalBranchInstruction.Operator.EQ, noTraceLabel)); + w.emit(getSysErr); + w.emit(ConstantInstruction.makeString(msg0)); + w.emit(callPrintln); + w.emitLabel(noTraceLabel); + w.emit(ThrowInstruction.make()); + } + }); + } + // this updates the data d + me.applyPatches(); + + if (disasm) { + w.write("Final ShrikeBT code:\n"); + (new Disassembler(d)).disassembleTo(w); + w.flush(); + } + } + } + + if (ci.isChanged()) { + ClassWriter cw = ci.emitClass(); + cw.addField(ClassReader.ACC_PUBLIC | ClassReader.ACC_STATIC, fieldName, Constants.TYPE_boolean, new ClassWriter.Element[0]); + instrumenter.outputModifiedClass(ci, cw); + } + } +} diff --git a/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrike/bench/InterfaceAnalyzer.java b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrike/bench/InterfaceAnalyzer.java new file mode 100644 index 000000000..0ea4e140a --- /dev/null +++ b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrike/bench/InterfaceAnalyzer.java @@ -0,0 +1,123 @@ +/******************************************************************************* + * 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 + * + * To change the template for this generated type comment go to Window - + * Preferences - Java - Code Generation - Code and Comments + */ +public class InterfaceAnalyzer { + final static class TypeStats { + int totalOccurrences; + int methodOccurrences; + int publicMethodOccurrences; + int foreignPublicMethodOccurrences; + int lastMUID; + } + + static HashMap typeStats = new HashMap(); + + public static void main(String[] args) throws Exception { + OfflineInstrumenter instrumenter = new OfflineInstrumenter(); + + 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 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); + } +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrike/bench/Mangler.java b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrike/bench/Mangler.java new file mode 100644 index 000000000..59405d9f5 --- /dev/null +++ b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrike/bench/Mangler.java @@ -0,0 +1,206 @@ +/******************************************************************************* + * 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.File; +import java.io.FileWriter; +import java.io.Writer; +import java.util.Random; + +import com.ibm.wala.shrikeBT.ArrayStoreInstruction; +import com.ibm.wala.shrikeBT.ConditionalBranchInstruction; +import com.ibm.wala.shrikeBT.ConstantInstruction; +import com.ibm.wala.shrikeBT.Constants; +import com.ibm.wala.shrikeBT.Disassembler; +import com.ibm.wala.shrikeBT.DupInstruction; +import com.ibm.wala.shrikeBT.GetInstruction; +import com.ibm.wala.shrikeBT.LoadInstruction; +import com.ibm.wala.shrikeBT.MethodData; +import com.ibm.wala.shrikeBT.MethodEditor; +import com.ibm.wala.shrikeBT.PutInstruction; +import com.ibm.wala.shrikeBT.StoreInstruction; +import com.ibm.wala.shrikeBT.SwapInstruction; +import com.ibm.wala.shrikeBT.Util; +import com.ibm.wala.shrikeBT.MethodEditor.Output; +import com.ibm.wala.shrikeBT.analysis.Verifier; +import com.ibm.wala.shrikeBT.info.LocalAllocator; +import com.ibm.wala.shrikeBT.shrikeCT.ClassInstrumenter; +import com.ibm.wala.shrikeBT.shrikeCT.OfflineInstrumenter; +import com.ibm.wala.shrikeCT.ClassWriter; + +/** + * This is a demo class. + * + * Class files are taken as input arguments (or if there are none, from standard + * input). The methods in those files are instrumented: we insert a + * System.err.println() at ever method call, and a System.err.println() at every + * method entry. + * + * In Unix, I run it like this: java -cp ~/dev/shrike/shrike + * com.ibm.wala.shrikeBT.shrikeCT.tools.Bench test.jar -o output.jar + * + * The instrumented classes are placed in the directory "output" under the + * current directory. Disassembled code is written to the file "report" under + * the current directory. + */ +public class Mangler { + private static OfflineInstrumenter instrumenter; + private static final boolean verify = true; + private static final boolean disasm = true; + + public static void main(String[] args) throws Exception { + for (int i = 0; i < 1; i++) { + instrumenter = new OfflineInstrumenter(); + + Writer w = new BufferedWriter(new FileWriter("report", false)); + + args = instrumenter.parseStandardArgs(args); + int seed; + try { + seed = Integer.parseInt(args[0]); + } catch (NumberFormatException ex) { + System.err.println("Invalid number: " + args[0]); + return; + } + + Random r = new Random(seed); + instrumenter.setPassUnmodifiedClasses(true); + instrumenter.beginTraversal(); + instrumenter.setOutputJar(new File("output.jar")); + ClassInstrumenter ci; + while ((ci = instrumenter.nextClass()) != null) { + doClass(ci, w, r); + } + instrumenter.close(); + } + } + + private static void doClass(final ClassInstrumenter ci, Writer w, final Random r) throws Exception { + final String className = ci.getReader().getName(); + w.write("Class: " + className + "\n"); + w.flush(); + + for (int m = 0; m < ci.getReader().getMethodCount(); m++) { + MethodData d = ci.visitMethod(m); + + // d could be null, e.g., if the method is abstract or native + if (d != null) { + w.write("Instrumenting " + ci.getReader().getMethodName(m) + " " + ci.getReader().getMethodType(m) + ":\n"); + w.flush(); + + if (disasm) { + w.write("Initial ShrikeBT code:\n"); + (new Disassembler(d)).disassembleTo(w); + w.flush(); + } + + if (verify) { + Verifier v = new Verifier(d); + v.verify(); + } + + final int passes = r.nextInt(4) + 1; + + for (int i = 0; i < passes; i++) { + final boolean doGet = true; // r.nextBoolean(); + final boolean doPut = true; // r.nextBoolean(); + final boolean doArrayStore = true; // r.nextBoolean(); + final int tmpInt = LocalAllocator.allocate(d, "I"); + final int tmpAny = LocalAllocator.allocate(d); + + final MethodEditor me = new MethodEditor(d); + me.beginPass(); + + me.visitInstructions(new MethodEditor.Visitor() { + public void visitGet(GetInstruction instruction) { + if (doGet && !instruction.isStatic()) { + insertBefore(new MethodEditor.Patch() { + public void emitTo(Output w) { + w.emit(DupInstruction.make(0)); + } + }); + insertAfter(new MethodEditor.Patch() { + public void emitTo(Output w) { + w.emit(SwapInstruction.make()); + w.emit(Util.makePut(Slots.class, "o")); + } + }); + } + } + + public void visitPut(PutInstruction instruction) { + if (doPut && !instruction.isStatic()) { + insertBefore(new MethodEditor.Patch() { + public void emitTo(Output w) { + w.emit(SwapInstruction.make()); + w.emit(DupInstruction.make(1)); + w.emit(SwapInstruction.make()); + } + }); + insertAfter(new MethodEditor.Patch() { + public void emitTo(Output w) { + w.emit(Util.makePut(Slots.class, "o")); + } + }); + } + } + + public void visitArrayStore(final ArrayStoreInstruction instruction) { + if (doArrayStore) { + final int label = me.allocateLabel(); + insertBefore(new MethodEditor.Patch() { + public void emitTo(Output w) { + String t = Util.getStackType(instruction.getType()); + w.emit(StoreInstruction.make(t, tmpAny)); + w.emit(StoreInstruction.make(Constants.TYPE_int, tmpInt)); + w.emit(DupInstruction.make(0)); + w.emit(LoadInstruction.make(Constants.TYPE_int, tmpInt)); + w.emit(LoadInstruction.make(t, tmpAny)); + if (t.equals(Constants.TYPE_int)) { + w.emit(DupInstruction.make(0)); + w.emit(ConstantInstruction.make(0)); + w.emit(ConditionalBranchInstruction.make(t, ConditionalBranchInstruction.Operator.EQ, label)); + w.emit(DupInstruction.make(0)); + w.emit(Util.makePut(Slots.class, "i")); + w.emitLabel(label); + } + } + }); + insertAfter(new MethodEditor.Patch() { + public void emitTo(Output w) { + w.emit(Util.makePut(Slots.class, "o")); + w.emit(LoadInstruction.make(Constants.TYPE_int, tmpInt)); + w.emit(Util.makePut(Slots.class, "i")); + } + }); + } + } + }); + + // this updates the data d + me.applyPatches(); + } + + if (disasm) { + w.write("Final ShrikeBT code:\n"); + (new Disassembler(d)).disassembleTo(w); + w.flush(); + } + } + } + + if (ci.isChanged()) { + ClassWriter cw = ci.emitClass(); + instrumenter.outputModifiedClass(ci, cw); + } + } +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrike/bench/Slots.java b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrike/bench/Slots.java new file mode 100644 index 000000000..03606b5e7 --- /dev/null +++ b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrike/bench/Slots.java @@ -0,0 +1,19 @@ +/******************************************************************************* + * 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; + +/** + * @author roca@us.ibm.com + */ +public class Slots { + public static Object o; + public static int i; +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrike/bench/Statistics.java b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrike/bench/Statistics.java new file mode 100644 index 000000000..76eda5961 --- /dev/null +++ b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrike/bench/Statistics.java @@ -0,0 +1,108 @@ +/******************************************************************************* + * 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.FileWriter; +import java.io.Writer; + +import com.ibm.wala.shrikeBT.Constants; +import com.ibm.wala.shrikeBT.Instruction; +import com.ibm.wala.shrikeBT.InvokeInstruction; +import com.ibm.wala.shrikeBT.MethodData; +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; + +/** + * This is a demo class. + * + * Class files are taken as input arguments (or if there are none, from standard + * input). The methods in those files are instrumented: we insert a + * System.err.println() at ever method call, and a System.err.println() at every + * method entry. + * + * In Unix, I run it like this: java -cp ~/dev/shrike/shrike + * com.ibm.wala.shrikeBT.shrikeCT.tools.Bench test.jar -o output.jar + * + * The instrumented classes are placed in the directory "output" under the + * current directory. Disassembled code is written to the file "report" under + * the current directory. + */ +public class Statistics { + private static OfflineInstrumenter instrumenter; + + public static void main(String[] args) throws Exception { + for (int i = 0; i < 1; i++) { + instrumenter = new OfflineInstrumenter(); + + Writer w = new BufferedWriter(new FileWriter("report", false)); + + args = instrumenter.parseStandardArgs(args); + + instrumenter.beginTraversal(); + ClassInstrumenter ci; + while ((ci = instrumenter.nextClass()) != null) { + doClass(ci, w); + } + instrumenter.close(); + w.close(); + } + } + + private static void doClass(final ClassInstrumenter ci, Writer w) throws Exception { + ClassReader cr = ci.getReader(); + final String className = cr.getName(); + w.write("Class: " + className + "\n"); + + boolean allPrivateConstructors = true; + boolean methodCallsConstructor = false; + boolean classInitCallsConstructor = false; + + for (int m = 0; m < cr.getMethodCount(); m++) { + MethodData d = ci.visitMethod(m); + + // d could be null, e.g., if the method is abstract or native + if (d != null) { + if (d.getName().equals("")) { + int f = cr.getMethodAccessFlags(m); + if ((f & Constants.ACC_PRIVATE) == 0 + && ((f & Constants.ACC_PROTECTED) == 0 || (cr.getAccessFlags() & Constants.ACC_FINAL) == 0)) { + allPrivateConstructors = false; + } + } + + int constructorCalls = 0; + Instruction[] instrs = d.getInstructions(); + for (int i = 0; i < instrs.length; i++) { + if (instrs[i] instanceof InvokeInstruction) { + InvokeInstruction invoke = (InvokeInstruction) instrs[i]; + if (invoke.getMethodName().equals("") && invoke.getClassType().equals(Util.makeType(className))) { + constructorCalls++; + } + } + } + if (!d.getName().equals("") && !d.getName().equals("")) { + if (constructorCalls > 0) { + methodCallsConstructor = true; + } + } else if (d.getName().equals("")) { + classInitCallsConstructor = true; + } + } + } + + if (allPrivateConstructors && !methodCallsConstructor && classInitCallsConstructor) { + w.write("Restricted Creation\n"); + } + } +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrike/copywriter/CopyWriter.java b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrike/copywriter/CopyWriter.java new file mode 100644 index 000000000..c6c05d2b7 --- /dev/null +++ b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrike/copywriter/CopyWriter.java @@ -0,0 +1,341 @@ +/******************************************************************************* + * 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.copywriter; + +import java.io.OutputStreamWriter; +import java.io.Writer; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.zip.ZipEntry; + +import com.ibm.wala.shrikeBT.Compiler; +import com.ibm.wala.shrikeBT.MethodData; +import com.ibm.wala.shrikeBT.Decoder.InvalidBytecodeException; +import com.ibm.wala.shrikeBT.shrikeCT.CTCompiler; +import com.ibm.wala.shrikeBT.shrikeCT.CTDecoder; +import com.ibm.wala.shrikeBT.shrikeCT.ClassInstrumenter; +import com.ibm.wala.shrikeBT.shrikeCT.OfflineInstrumenter; +import com.ibm.wala.shrikeCT.ClassReader; +import com.ibm.wala.shrikeCT.ClassWriter; +import com.ibm.wala.shrikeCT.CodeReader; +import com.ibm.wala.shrikeCT.CodeWriter; +import com.ibm.wala.shrikeCT.ConstantPoolParser; +import com.ibm.wala.shrikeCT.ConstantValueReader; +import com.ibm.wala.shrikeCT.ConstantValueWriter; +import com.ibm.wala.shrikeCT.ExceptionsReader; +import com.ibm.wala.shrikeCT.ExceptionsWriter; +import com.ibm.wala.shrikeCT.InnerClassesReader; +import com.ibm.wala.shrikeCT.InnerClassesWriter; +import com.ibm.wala.shrikeCT.InvalidClassFileException; +import com.ibm.wala.shrikeCT.LocalVariableTableReader; +import com.ibm.wala.shrikeCT.LocalVariableTableWriter; +import com.ibm.wala.shrikeCT.SourceFileReader; +import com.ibm.wala.shrikeCT.SourceFileWriter; +import com.ibm.wala.shrikeCT.ClassReader.AttrIterator; +import com.ibm.wala.shrikeCT.ClassWriter.Element; + +public class CopyWriter { + private static final String USAGE = "IBM CopyWriter Tool\n" + "This tool takes the following command line options:\n" + + " ... Process the classes from these jars\n" + + " -o Put the resulting classes into \n" + + " -c Make the copyright string be\n" + + " '\u00A9 Copyright '"; + private static OfflineInstrumenter instrumenter; + public static String copyright; + public static final String copyrightAttrName = "com.ibm.Copyright"; + + private int replaceWith; + private int replace; + + static class UnknownAttributeException extends Exception { + private static final long serialVersionUID = 8845177787110364793L; + + UnknownAttributeException(String t) { + super("Attribute '" + t + "' not understood"); + } + } + + public static void main(String[] args) throws Exception { + if (args.length == 0) { + System.err.println(USAGE); + System.exit(1); + } + + for (int i = 0; i < args.length - 1; i++) { + if (args[i].equals("-c")) { + copyright = "\u00A9 Copyright " + args[i + 1]; + String[] newArgs = new String[args.length - 2]; + System.arraycopy(args, 0, newArgs, 0, i); + System.arraycopy(args, i + 2, newArgs, i, newArgs.length - i); + args = newArgs; + break; + } + } + if (copyright == null) { + System.err.println(USAGE); + System.exit(1); + } + + final ArrayList entries = new ArrayList(); + + instrumenter = new OfflineInstrumenter(); + instrumenter.setManifestBuilder(new OfflineInstrumenter.ManifestBuilder() { + public void addEntry(ZipEntry ze) { + entries.add(ze); + } + }); + instrumenter.parseStandardArgs(args); + instrumenter.setJARComment(copyright); + instrumenter.beginTraversal(); + ClassInstrumenter ci; + CopyWriter cw = new CopyWriter(); + while ((ci = instrumenter.nextClass()) != null) { + try { + cw.doClass(ci); + } catch (UnknownAttributeException ex) { + System.err.println(ex.getMessage() + " in " + instrumenter.getLastClassResourceName()); + } + } + + instrumenter.writeUnmodifiedClasses(); + + Writer w = new OutputStreamWriter(instrumenter.addOutputJarEntry(new ZipEntry("IBM-Copyright"))); + w.write(copyright + "\n"); + for (Iterator iter = entries.iterator(); iter.hasNext();) { + ZipEntry ze = iter.next(); + w.write(" " + ze.getName() + "\n"); + } + w.write(copyright + "\n"); + w.flush(); + instrumenter.endOutputJarEntry(); + + instrumenter.close(); + } + + private int transformCPIndex(int i) { + if (i == replace) { + return replaceWith; + } else { + return i; + } + } + + private Element transformAttribute(ClassReader cr, int m, ClassWriter w, AttrIterator iter) throws InvalidClassFileException, + UnknownAttributeException, InvalidBytecodeException { + String name = iter.getName(); + + boolean needTransform = true; + if (name.equals("Synthetic") || name.equals("Deprecated") || name.equals("LineNumberTable")) { + needTransform = false; + } + + int offset = iter.getRawOffset(); + int end = offset + iter.getRawSize(); + + if (needTransform) { + needTransform = false; + for (int i = offset; i + 1 < end; i++) { + if (cr.getUShort(i) == replace) { + break; + } + } + } + + if (!needTransform) { + return new ClassWriter.RawElement(cr.getBytes(), offset, end - offset); + } + + if (name.equals("Code")) { + CodeReader r = new CodeReader(iter); + CTDecoder decoder = new CTDecoder(r); + decoder.decode(); + MethodData md = new MethodData(decoder, cr.getMethodAccessFlags(m), CTDecoder.convertClassToType(cr.getName()), cr + .getMethodName(m), cr.getMethodType(m)); + CTCompiler compiler = new CTCompiler(w, md); + compiler.compile(); + if (compiler.getAuxiliaryMethods().length > 0) + throw new Error("Where did this auxiliary method come from?"); + Compiler.Output out = compiler.getOutput(); + CodeWriter cw = new CodeWriter(w); + cw.setMaxLocals(out.getMaxLocals()); + cw.setMaxStack(out.getMaxStack()); + cw.setCode(out.getCode()); + cw.setRawHandlers(out.getRawHandlers()); + ClassReader.AttrIterator iterator = new ClassReader.AttrIterator(); + r.initAttributeIterator(iterator); + cw.setAttributes(collectAttributes(cr, m, w, iterator)); + return cw; + } else if (name.equals("ConstantValue")) { + ConstantValueReader r = new ConstantValueReader(iter); + ConstantValueWriter cw = new ConstantValueWriter(w); + cw.setValueCPIndex(transformCPIndex(r.getValueCPIndex())); + return cw; + } else if (name.equals("SourceFile")) { + SourceFileReader r = new SourceFileReader(iter); + SourceFileWriter cw = new SourceFileWriter(w); + cw.setSourceFileCPIndex(transformCPIndex(r.getSourceFileCPIndex())); + return cw; + } else if (name.equals("LocalVariableTableReader")) { + LocalVariableTableReader lr = new LocalVariableTableReader(iter); + LocalVariableTableWriter lw = new LocalVariableTableWriter(w); + int[] table = lr.getRawTable(); + for (int i = 0; i < table.length; i += 5) { + table[i + 2] = transformCPIndex(table[i + 2]); + table[i + 3] = transformCPIndex(table[i + 3]); + } + lw.setRawTable(table); + return lw; + } else if (name.equals("Exceptions")) { + ExceptionsReader lr = new ExceptionsReader(iter); + ExceptionsWriter lw = new ExceptionsWriter(w); + int[] table = lr.getRawTable(); + for (int i = 0; i < table.length; i++) { + table[i] = transformCPIndex(table[i]); + } + lw.setRawTable(table); + return lw; + } else if (name.equals("InnerClasses")) { + InnerClassesReader lr = new InnerClassesReader(iter); + InnerClassesWriter lw = new InnerClassesWriter(w); + int[] table = lr.getRawTable(); + for (int i = 0; i < table.length; i += 4) { + table[i] = transformCPIndex(table[i]); + table[i + 1] = transformCPIndex(table[i + 1]); + table[i + 2] = transformCPIndex(table[i + 2]); + } + lw.setRawTable(table); + return lw; + } + + throw new UnknownAttributeException(name); + } + + private Element[] collectAttributes(ClassReader cr, int m, ClassWriter w, AttrIterator iter) throws InvalidClassFileException, + UnknownAttributeException, InvalidBytecodeException { + Element[] elems = new Element[iter.getRemainingAttributesCount()]; + for (int i = 0; i < elems.length; i++) { + elems[i] = transformAttribute(cr, m, w, iter); + iter.advance(); + } + return elems; + } + + private int copyEntry(ConstantPoolParser cp, ClassWriter w, int i) throws InvalidClassFileException { + byte t = cp.getItemType(i); + switch (t) { + case ClassReader.CONSTANT_String: + return w.addCPString(cp.getCPString(i)); + case ClassReader.CONSTANT_Class: + return w.addCPClass(cp.getCPClass(i)); + case ClassReader.CONSTANT_FieldRef: + return w.addCPFieldRef(cp.getCPRefClass(i), cp.getCPRefName(i), cp.getCPRefType(i)); + case ClassReader.CONSTANT_InterfaceMethodRef: + return w.addCPInterfaceMethodRef(cp.getCPRefClass(i), cp.getCPRefName(i), cp.getCPRefType(i)); + case ClassReader.CONSTANT_MethodRef: + return w.addCPMethodRef(cp.getCPRefClass(i), cp.getCPRefName(i), cp.getCPRefType(i)); + case ClassReader.CONSTANT_NameAndType: + return w.addCPNAT(cp.getCPNATName(i), cp.getCPNATType(i)); + case ClassReader.CONSTANT_Integer: + return w.addCPInt(cp.getCPInt(i)); + case ClassReader.CONSTANT_Float: + return w.addCPFloat(cp.getCPFloat(i)); + case ClassReader.CONSTANT_Long: + return w.addCPLong(cp.getCPLong(i)); + case ClassReader.CONSTANT_Double: + return w.addCPDouble(cp.getCPDouble(i)); + case ClassReader.CONSTANT_Utf8: + return w.addCPUtf8(cp.getCPUtf8(i)); + } + return -1; + } + + private void doClass(final ClassInstrumenter ci) throws Exception { + /* + * Our basic strategy is to make the first element of the constant pool be + * the copyright string (as a UTF8 constant pool item). This requires us to + * parse and emit any class data which might refer to that constant pool + * item (#1). We will assume that any attribute which refers to that + * constant pool item must contain the byte sequence '00 01', so we can just + * copy over any attributes which don't contain that byte sequence. If we + * detect an unknown attribute type containing the sequence '00 01', then we + * will abort. + */ + ClassReader cr = ci.getReader(); + ClassWriter w = new ClassWriter(); + + // Make sure that when we're moving over the old constant pool, + // anytime we add a new entry it really is added and we don't just + // reuse an existing entry. + w.setForceAddCPEntries(true); + + // Make the first string in the constant pool be the copyright string + int r = w.addCPUtf8(copyright); + if (r != 1) + throw new Error("Invalid constant pool index: " + r); + + // Now add the rest of the CP entries + ConstantPoolParser cp = cr.getCP(); + int CPCount = cp.getItemCount(); + + if (1 < CPCount) { + switch (cp.getItemType(1)) { + case ClassReader.CONSTANT_Long: + case ClassReader.CONSTANT_Double: + // item 1 is a double-word item, so the next real item is at 3 + // to make sure item 3 is allocated at index 3, we'll need to + // insert a dummy entry at index 2 + r = w.addCPUtf8(""); + if (r != 2) + throw new Error("Invalid constant pool index for dummy: " + r); + break; + } + } + for (int i = 2; i < CPCount; i++) { + r = copyEntry(cp, w, i); + if (r != -1 && r != i) + throw new Error("Invalid constant pool index allocated: " + r + ", expected " + i); + } + w.setForceAddCPEntries(false); + + // add CP entry we replaced + replaceWith = copyEntry(cp, w, 1); + replace = 1; + + // emit class + w.setMajorVersion(cr.getMajorVersion()); + w.setMinorVersion(cr.getMinorVersion()); + w.setAccessFlags(cr.getAccessFlags()); + w.setName(cr.getName()); + w.setSuperName(cr.getSuperName()); + w.setInterfaceNames(cr.getInterfaceNames()); + + ClassReader.AttrIterator iter = new ClassReader.AttrIterator(); + + int fieldCount = cr.getFieldCount(); + for (int i = 0; i < fieldCount; i++) { + cr.initFieldAttributeIterator(i, iter); + w.addField(cr.getFieldAccessFlags(i), cr.getFieldName(i), cr.getFieldType(i), collectAttributes(cr, i, w, iter)); + } + + int methodCount = cr.getMethodCount(); + for (int i = 0; i < methodCount; i++) { + cr.initMethodAttributeIterator(i, iter); + w.addMethod(cr.getMethodAccessFlags(i), cr.getMethodName(i), cr.getMethodType(i), collectAttributes(cr, i, w, iter)); + } + + cr.initClassAttributeIterator(iter); + for (; iter.isValid(); iter.advance()) { + w.addClassAttribute(transformAttribute(cr, 0, w, iter)); + } + + instrumenter.outputModifiedClass(ci, w); + } +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrike/tools/ExtractMatchingClasses.java b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrike/tools/ExtractMatchingClasses.java new file mode 100644 index 000000000..667df5e99 --- /dev/null +++ b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrike/tools/ExtractMatchingClasses.java @@ -0,0 +1,66 @@ +/******************************************************************************* + * 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.tools; + +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.Enumeration; +import java.util.jar.JarEntry; +import java.util.jar.JarFile; +import java.util.jar.JarOutputStream; + +public class ExtractMatchingClasses { + private static boolean matchEntry(JarFile[] matches, JarEntry e) { + for (int i = 0; i < matches.length; i++) { + if (matches[i].getEntry(e.getName()) != null) { + return true; + } + } + return false; + } + + private static void readFully(InputStream s, byte[] b) throws IOException { + int offset = 0; + while (offset < b.length) { + int read = s.read(b, offset, b.length - offset); + offset += read; + } + } + + public static void main(String[] args) throws Exception { + String in = args[0]; + String out = args[1]; + String[] match = new String[args.length - 2]; + System.arraycopy(args, 2, match, 0, match.length); + + JarFile inJar = new JarFile(in); + JarOutputStream outJar = new JarOutputStream(new FileOutputStream(out)); + JarFile[] matches = new JarFile[match.length]; + for (int i = 0; i < match.length; i++) { + matches[i] = new JarFile(match[i]); + } + + for (Enumeration e = inJar.entries(); e.hasMoreElements();) { + JarEntry entry = (JarEntry) e.nextElement(); + + if (matchEntry(matches, entry)) { + outJar.putNextEntry(entry); + byte[] data = new byte[(int) entry.getSize()]; + InputStream stream = inJar.getInputStream(entry); + readFully(stream, data); + outJar.write(data); + outJar.flush(); + } + } + outJar.close(); + } +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/ArrayLengthInstruction.java b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/ArrayLengthInstruction.java new file mode 100644 index 000000000..9a86a3c65 --- /dev/null +++ b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/ArrayLengthInstruction.java @@ -0,0 +1,60 @@ +/******************************************************************************* + * 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.shrikeBT; + +/** + * This class represents arraylength instructions. + */ +final public class ArrayLengthInstruction extends Instruction { + protected ArrayLengthInstruction() { + opcode = (byte) OP_arraylength; + } + + private static ArrayLengthInstruction preallocated = new ArrayLengthInstruction(); + + public static ArrayLengthInstruction make() { + return preallocated; + } + + public boolean equals(Object o) { + return o instanceof ArrayLengthInstruction; + } + + public int hashCode() { + return 3180901; + } + + public int getPoppedCount() { + return 1; + } + + public String getPushedType(String[] types) { + return Constants.TYPE_int; + } + + public byte getPushedWordSize() { + return 1; + } + + public void visit(Visitor v) { + v.visitArrayLength(this); + } + + public String toString() { + return "ArrayLength()"; + } + /* (non-Javadoc) + * @see com.ibm.domo.cfg.IInstruction#isPEI() + */ + public boolean isPEI() { + return true; + } +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/ArrayLoadInstruction.java b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/ArrayLoadInstruction.java new file mode 100644 index 000000000..0ce708282 --- /dev/null +++ b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/ArrayLoadInstruction.java @@ -0,0 +1,93 @@ +/******************************************************************************* + * 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.shrikeBT; + +/** + * This class represents the ?aload instructions. + */ +final public class ArrayLoadInstruction extends Instruction { + protected ArrayLoadInstruction(short opcode) { + this.opcode = opcode; + } + + private final static ArrayLoadInstruction[] preallocated = preallocate(); + + private static ArrayLoadInstruction[] preallocate() { + ArrayLoadInstruction[] r = new ArrayLoadInstruction[OP_saload - OP_iaload + 2]; + for (short i = OP_iaload; i <= OP_saload; i++) { + r[i - OP_iaload] = new ArrayLoadInstruction(i); + } + r[OP_saload - OP_iaload + 1] = r[OP_baload - OP_iaload]; + return r; + } + + public static ArrayLoadInstruction make(String type) { + int i = Util.getTypeIndex(type); + if (i < 0 || i > TYPE_boolean_index) { + throw new IllegalArgumentException("Invalid type " + type + " for ArrayLoadInstruction"); + } + return preallocated[i]; + } + + public boolean equals(Object o) { + if (o instanceof ArrayLoadInstruction) { + ArrayLoadInstruction i = (ArrayLoadInstruction) o; + return i.opcode == opcode; + } else { + return false; + } + } + + public int hashCode() { + return opcode + 9109101; + } + + public int getPoppedCount() { + return 2; + } + + public String toString() { + return "ArrayLoad(" + getType() + ")"; + } + + public String getPushedType(String[] types) { + if (types == null) { + return getType(); + } else { + String t = types[1]; + if (t.startsWith("[")) { + return t.substring(1); + } else if (t.equals(TYPE_null)) { + return TYPE_null; + } else { + return TYPE_unknown; + } + } + } + + public byte getPushedWordSize() { + return Util.getWordSize(getType()); + } + + public String getType() { + return Constants.indexedTypes[opcode - OP_iaload]; + } + + public void visit(Visitor v) { + v.visitArrayLoad(this); + } + /* (non-Javadoc) + * @see com.ibm.domo.cfg.IInstruction#isPEI() + */ + public boolean isPEI() { + return true; + } +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/ArrayStoreInstruction.java b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/ArrayStoreInstruction.java new file mode 100644 index 000000000..85e60229d --- /dev/null +++ b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/ArrayStoreInstruction.java @@ -0,0 +1,74 @@ +/******************************************************************************* + * 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.shrikeBT; + +/** + * This class represents the ?astore instructions. + */ +final public class ArrayStoreInstruction extends Instruction { + protected ArrayStoreInstruction(short opcode) { + this.opcode = opcode; + } + + private final static ArrayStoreInstruction[] preallocated = preallocate(); + + private static ArrayStoreInstruction[] preallocate() { + ArrayStoreInstruction[] r = new ArrayStoreInstruction[OP_sastore - OP_iastore + 2]; + for (short i = OP_iastore; i <= OP_sastore; i++) { + r[i - OP_iastore] = new ArrayStoreInstruction(i); + } + r[OP_sastore - OP_iastore + 1] = r[OP_baload - OP_iaload]; + return r; + } + + public static ArrayStoreInstruction make(String type) { + int i = Util.getTypeIndex(type); + if (i < 0 || i > TYPE_boolean_index) { + throw new IllegalArgumentException("Invalid type " + type + " for ArrayStoreInstruction"); + } + return preallocated[i]; + } + + public boolean equals(Object o) { + if (o instanceof ArrayStoreInstruction) { + ArrayStoreInstruction i = (ArrayStoreInstruction) o; + return i.opcode == opcode; + } else { + return false; + } + } + + public int hashCode() { + return opcode + 148791; + } + + public int getPoppedCount() { + return 3; + } + + public String getType() { + return Decoder.indexedTypes[opcode - OP_iastore]; + } + + public String toString() { + return "ArrayStore(" + getType() + ")"; + } + + public void visit(Visitor v) { + v.visitArrayStore(this); + } + /* (non-Javadoc) + * @see com.ibm.domo.cfg.IInstruction#isPEI() + */ + public boolean isPEI() { + return true; + } +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/BinaryOpInstruction.java b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/BinaryOpInstruction.java new file mode 100644 index 000000000..3130c10ab --- /dev/null +++ b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/BinaryOpInstruction.java @@ -0,0 +1,130 @@ +/******************************************************************************* + * 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.shrikeBT; + +/** + * This class represents binary operator instructions for which the operands and + * the result all have the same type. + */ +final public class BinaryOpInstruction extends Instruction { + public interface IOperator {} + + public enum Operator implements IOperator { + ADD, SUB, MUL, DIV, REM, AND, OR, XOR; + + @Override + public String toString() { + return super.toString().toLowerCase(); + } + } + + protected BinaryOpInstruction(short opcode) { + this.opcode = opcode; + } + + private final static BinaryOpInstruction[] arithmeticOps = preallocateArithmeticOps(); + private final static BinaryOpInstruction[] logicalOps = preallocateLogicalOps(); + + private static BinaryOpInstruction[] preallocateArithmeticOps() { + BinaryOpInstruction[] r = new BinaryOpInstruction[OP_drem - OP_iadd + 1]; + for (short i = OP_iadd; i <= OP_drem; i++) { + r[i - OP_iadd] = new BinaryOpInstruction(i); + } + return r; + } + + private static BinaryOpInstruction[] preallocateLogicalOps() { + BinaryOpInstruction[] r = new BinaryOpInstruction[OP_lxor - OP_iand + 1]; + for (short i = OP_iand; i <= OP_lxor; i++) { + r[i - OP_iand] = new BinaryOpInstruction(i); + } + return r; + } + + public static BinaryOpInstruction make(String type, Operator operator) { + int t = Util.getTypeIndex(type); + if (t < 0) { + throw new IllegalArgumentException("Invalid type for BinaryOp: " + type); + } + + if (operator.compareTo(Operator.REM) <= 0) { + if (t > TYPE_double_index) { + throw new IllegalArgumentException("Invalid type for BinaryOp: " + type); + } + return arithmeticOps[(operator.ordinal() - Operator.ADD.ordinal()) * 4 + t]; + } else { + if (t > TYPE_long_index) { + throw new IllegalArgumentException("Cannot use logical binaryOps on floating point type: " + type); + } + return logicalOps[(operator.ordinal() - Operator.AND.ordinal()) * 2 + t]; + } + } + + public boolean equals(Object o) { + if (o instanceof BinaryOpInstruction) { + BinaryOpInstruction i = (BinaryOpInstruction) o; + return i.opcode == opcode; + } else { + return false; + } + } + + /** + * don't call this unless you really know what you're doing + */ + public Operator getOperator() { + if (opcode < OP_iand) { + return Operator.values()[(opcode - OP_iadd) / 4]; + } else { + return Operator.values()[(opcode - OP_iand) / 2]; + } + } + + public int hashCode() { + return opcode + 13901901; + } + + public int getPoppedCount() { + return 2; + } + + public String getPushedType(String[] types) { + return getType(); + } + + public byte getPushedWordSize() { + return Util.getWordSize(getType()); + } + + public String getType() { + int t; + if (opcode < OP_iand) { + t = (opcode - OP_iadd) & 3; + } else { + t = (opcode - OP_iand) & 1; + } + return indexedTypes[t]; + } + + public void visit(Visitor v) { + v.visitBinaryOp(this); + } + + public String toString() { + return "BinaryOp(" + getType() + "," + getOperator() + ")"; + } + /* (non-Javadoc) + * @see com.ibm.domo.cfg.IInstruction#isPEI() + */ + public boolean isPEI() { + return opcode == Constants.OP_idiv; + } +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/BytecodeConstants.java b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/BytecodeConstants.java new file mode 100644 index 000000000..19bedfd40 --- /dev/null +++ b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/BytecodeConstants.java @@ -0,0 +1,649 @@ +/******************************************************************************* + * 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.shrikeBT; + +/** + * Information about java byte codes that appear in the "code" attribute + * of a .class file. + * + * @author Bowen Alpern + * @author Derek Lieber + * @author Stephen Fink + */ +public interface BytecodeConstants { + + // The following mnemonics are defined in Chapter 10 of The Java Virtual Machine Specification. + // + public static final int JBC_nop = 0; + public static final int JBC_aconst_null = 1; + public static final int JBC_iconst_m1 = 2; + public static final int JBC_iconst_0 = 3; + public static final int JBC_iconst_1 = 4; + public static final int JBC_iconst_2 = 5; + public static final int JBC_iconst_3 = 6; + public static final int JBC_iconst_4 = 7; + public static final int JBC_iconst_5 = 8; + public static final int JBC_lconst_0 = 9; + public static final int JBC_lconst_1 = 10; + public static final int JBC_fconst_0 = 11; + public static final int JBC_fconst_1 = 12; + public static final int JBC_fconst_2 = 13; + public static final int JBC_dconst_0 = 14; + public static final int JBC_dconst_1 = 15; + public static final int JBC_bipush = 16; + public static final int JBC_sipush = 17; + public static final int JBC_ldc = 18; + public static final int JBC_ldc_w = 19; + public static final int JBC_ldc2_w = 20; + public static final int JBC_iload = 21; + public static final int JBC_lload = 22; + public static final int JBC_fload = 23; + public static final int JBC_dload = 24; + public static final int JBC_aload = 25; + public static final int JBC_iload_0 = 26; + public static final int JBC_iload_1 = 27; + public static final int JBC_iload_2 = 28; + public static final int JBC_iload_3 = 29; + public static final int JBC_lload_0 = 30; + public static final int JBC_lload_1 = 31; + public static final int JBC_lload_2 = 32; + public static final int JBC_lload_3 = 33; + public static final int JBC_fload_0 = 34; + public static final int JBC_fload_1 = 35; + public static final int JBC_fload_2 = 36; + public static final int JBC_fload_3 = 37; + public static final int JBC_dload_0 = 38; + public static final int JBC_dload_1 = 39; + public static final int JBC_dload_2 = 40; + public static final int JBC_dload_3 = 41; + public static final int JBC_aload_0 = 42; + public static final int JBC_aload_1 = 43; + public static final int JBC_aload_2 = 44; + public static final int JBC_aload_3 = 45; + public static final int JBC_iaload = 46; + public static final int JBC_laload = 47; + public static final int JBC_faload = 48; + public static final int JBC_daload = 49; + public static final int JBC_aaload = 50; + public static final int JBC_baload = 51; + public static final int JBC_caload = 52; + public static final int JBC_saload = 53; + public static final int JBC_istore = 54; + public static final int JBC_lstore = 55; + public static final int JBC_fstore = 56; + public static final int JBC_dstore = 57; + public static final int JBC_astore = 58; + public static final int JBC_istore_0 = 59; + public static final int JBC_istore_1 = 60; + public static final int JBC_istore_2 = 61; + public static final int JBC_istore_3 = 62; + public static final int JBC_lstore_0 = 63; + public static final int JBC_lstore_1 = 64; + public static final int JBC_lstore_2 = 65; + public static final int JBC_lstore_3 = 66; + public static final int JBC_fstore_0 = 67; + public static final int JBC_fstore_1 = 68; + public static final int JBC_fstore_2 = 69; + public static final int JBC_fstore_3 = 70; + public static final int JBC_dstore_0 = 71; + public static final int JBC_dstore_1 = 72; + public static final int JBC_dstore_2 = 73; + public static final int JBC_dstore_3 = 74; + public static final int JBC_astore_0 = 75; + public static final int JBC_astore_1 = 76; + public static final int JBC_astore_2 = 77; + public static final int JBC_astore_3 = 78; + public static final int JBC_iastore = 79; + public static final int JBC_lastore = 80; + public static final int JBC_fastore = 81; + public static final int JBC_dastore = 82; + public static final int JBC_aastore = 83; + public static final int JBC_bastore = 84; + public static final int JBC_castore = 85; + public static final int JBC_sastore = 86; + public static final int JBC_pop = 87; + public static final int JBC_pop2 = 88; + public static final int JBC_dup = 89; + public static final int JBC_dup_x1 = 90; + public static final int JBC_dup_x2 = 91; + public static final int JBC_dup2 = 92; + public static final int JBC_dup2_x1 = 93; + public static final int JBC_dup2_x2 = 94; + public static final int JBC_swap = 95; + public static final int JBC_iadd = 96; + public static final int JBC_ladd = 97; + public static final int JBC_fadd = 98; + public static final int JBC_dadd = 99; + public static final int JBC_isub = 100; + public static final int JBC_lsub = 101; + public static final int JBC_fsub = 102; + public static final int JBC_dsub = 103; + public static final int JBC_imul = 104; + public static final int JBC_lmul = 105; + public static final int JBC_fmul = 106; + public static final int JBC_dmul = 107; + public static final int JBC_idiv = 108; + public static final int JBC_ldiv = 109; + public static final int JBC_fdiv = 110; + public static final int JBC_ddiv = 111; + public static final int JBC_irem = 112; + public static final int JBC_lrem = 113; + public static final int JBC_frem = 114; + public static final int JBC_drem = 115; + public static final int JBC_ineg = 116; + public static final int JBC_lneg = 117; + public static final int JBC_fneg = 118; + public static final int JBC_dneg = 119; + public static final int JBC_ishl = 120; + public static final int JBC_lshl = 121; + public static final int JBC_ishr = 122; + public static final int JBC_lshr = 123; + public static final int JBC_iushr = 124; + public static final int JBC_lushr = 125; + public static final int JBC_iand = 126; + public static final int JBC_land = 127; + public static final int JBC_ior = 128; + public static final int JBC_lor = 129; + public static final int JBC_ixor = 130; + public static final int JBC_lxor = 131; + public static final int JBC_iinc = 132; + public static final int JBC_i2l = 133; + public static final int JBC_i2f = 134; + public static final int JBC_i2d = 135; + public static final int JBC_l2i = 136; + public static final int JBC_l2f = 137; + public static final int JBC_l2d = 138; + public static final int JBC_f2i = 139; + public static final int JBC_f2l = 140; + public static final int JBC_f2d = 141; + public static final int JBC_d2i = 142; + public static final int JBC_d2l = 143; + public static final int JBC_d2f = 144; + public static final int JBC_int2byte = 145; + public static final int JBC_int2char = 146; + public static final int JBC_int2short = 147; + public static final int JBC_lcmp = 148; + public static final int JBC_fcmpl = 149; + public static final int JBC_fcmpg = 150; + public static final int JBC_dcmpl = 151; + public static final int JBC_dcmpg = 152; + public static final int JBC_ifeq = 153; + public static final int JBC_ifne = 154; + public static final int JBC_iflt = 155; + public static final int JBC_ifge = 156; + public static final int JBC_ifgt = 157; + public static final int JBC_ifle = 158; + public static final int JBC_if_icmpeq = 159; + public static final int JBC_if_icmpne = 160; + public static final int JBC_if_icmplt = 161; + public static final int JBC_if_icmpge = 162; + public static final int JBC_if_icmpgt = 163; + public static final int JBC_if_icmple = 164; + public static final int JBC_if_acmpeq = 165; + public static final int JBC_if_acmpne = 166; + public static final int JBC_goto = 167; + public static final int JBC_jsr = 168; + public static final int JBC_ret = 169; + public static final int JBC_tableswitch = 170; + public static final int JBC_lookupswitch = 171; + public static final int JBC_ireturn = 172; + public static final int JBC_lreturn = 173; + public static final int JBC_freturn = 174; + public static final int JBC_dreturn = 175; + public static final int JBC_areturn = 176; + public static final int JBC_return = 177; + public static final int JBC_getstatic = 178; + public static final int JBC_putstatic = 179; + public static final int JBC_getfield = 180; + public static final int JBC_putfield = 181; + public static final int JBC_invokevirtual = 182; + public static final int JBC_invokespecial = 183; + public static final int JBC_invokestatic = 184; + public static final int JBC_invokeinterface = 185; + public static final int JBC_xxxunusedxxx = 186; + public static final int JBC_new = 187; + public static final int JBC_newarray = 188; + public static final int JBC_anewarray = 189; + public static final int JBC_arraylength = 190; + public static final int JBC_athrow = 191; + public static final int JBC_checkcast = 192; + public static final int JBC_instanceof = 193; + public static final int JBC_monitorenter = 194; + public static final int JBC_monitorexit = 195; + public static final int JBC_wide = 196; + public static final int JBC_multianewarray = 197; + public static final int JBC_ifnull = 198; + public static final int JBC_ifnonnull = 199; + public static final int JBC_goto_w = 200; + public static final int JBC_jsr_w = 201; + + public static final int JBC_impdep1 = 254; + public static final int JBC_impdep2 = 255; + + // Length of each instruction introduced by the above bytecodes. + // -1 indicates a variable length instruction. + // -2 indicates an unused instruction. + // + public static final byte JBC_length[] = { 1, // nop + 1, // aconst_null + 1, // iconst_m1 + 1, // iconst_0 + 1, // iconst_1 + 1, // iconst_2 + 1, // iconst_3 + 1, // iconst_4 + 1, // iconst_5 + 1, // lconst_0 + 1, // lconst_1 + 1, // fconst_0 + 1, // fconst_1 + 1, // fconst_2 + 1, // dconst_0 + 1, // dconst_1 + 2, // bipush + 3, // sipush + 2, // ldc + 3, // ldc_w + 3, // ldc2_w + 2, // iload + 2, // lload + 2, // fload + 2, // dload + 2, // aload + 1, // iload_0 + 1, // iload_1 + 1, // iload_2 + 1, // iload_3 + 1, // lload_0 + 1, // lload_1 + 1, // lload_2 + 1, // lload_3 + 1, // fload_0 + 1, // fload_1 + 1, // fload_2 + 1, // fload_3 + 1, // dload_0 + 1, // dload_1 + 1, // dload_2 + 1, // dload_3 + 1, // aload_0 + 1, // aload_1 + 1, // aload_2 + 1, // aload_3 + 1, // iaload + 1, // laload + 1, // faload + 1, // daload + 1, // aaload + 1, // baload + 1, // caload + 1, // saload + 2, // istore + 2, // lstore + 2, // fstore + 2, // dstore + 2, // astore + 1, // istore_0 + 1, // istore_1 + 1, // istore_2 + 1, // istore_3 + 1, // lstore_0 + 1, // lstore_1 + 1, // lstore_2 + 1, // lstore_3 + 1, // fstore_0 + 1, // fstore_1 + 1, // fstore_2 + 1, // fstore_3 + 1, // dstore_0 + 1, // dstore_1 + 1, // dstore_2 + 1, // dstore_3 + 1, // astore_0 + 1, // astore_1 + 1, // astore_2 + 1, // astore_3 + 1, // iastore + 1, // lastore + 1, // fastore + 1, // dastore + 1, // aastore + 1, // bastore + 1, // castore + 1, // sastore + 1, // pop + 1, // pop2 + 1, // dup + 1, // dup_x1 + 1, // dup_x2 + 1, // dup2 + 1, // dup2_x1 + 1, // dup2_x2 + 1, // swap + 1, // iadd + 1, // ladd + 1, // fadd + 1, // dadd + 1, // isub + 1, // lsub + 1, // fsub + 1, // dsub + 1, // imul + 1, // lmul + 1, // fmul + 1, // dmul + 1, // idiv + 1, // ldiv + 1, // fdiv + 1, // ddiv + 1, // irem + 1, // lrem + 1, // frem + 1, // drem + 1, // ineg + 1, // lneg + 1, // fneg + 1, // dneg + 1, // ishl + 1, // lshl + 1, // ishr + 1, // lshr + 1, // iushr + 1, // lushr + 1, // iand + 1, // land + 1, // ior + 1, // lor + 1, // ixor + 1, // lxor + 3, // iinc + 1, // i2l + 1, // i2f + 1, // i2d + 1, // l2i + 1, // l2f + 1, // l2d + 1, // f2i + 1, // f2l + 1, // f2d + 1, // d2i + 1, // d2l + 1, // d2f + 1, // int2byte + 1, // int2char + 1, // int2short + 1, // lcmp + 1, // fcmpl + 1, // fcmpg + 1, // dcmpl + 1, // dcmpg + 3, // ifeq + 3, // ifne + 3, // iflt + 3, // ifge + 3, // ifgt + 3, // ifle + 3, // if_icmpeq + 3, // if_icmpne + 3, // if_icmplt + 3, // if_icmpge + 3, // if_icmpgt + 3, // if_icmple + 3, // if_acmpeq + 3, // if_acmpne + 3, // goto + 3, // jsr + 2, // ret + -1, // tableswitch + -1, // lookupswitch + 1, // ireturn + 1, // lreturn + 1, // freturn + 1, // dreturn + 1, // areturn + 1, // return + 3, // getstatic + 3, // putstatic + 3, // getfield + 3, // putfield + 3, // invokevirtual + 3, // invokenonvirtual + 3, // invokestatic + 5, // invokeinterface + -2, // xxxunusedxxx + 3, // new + 2, // newarray + 3, // anewarray + 1, // arraylength + 1, // athrow + 3, // checkcast + 3, // instanceof + 1, // monitorenter + 1, // monitorexit + -1, // wide + 4, // multianewarray + 3, // ifnull + 3, // ifnonnull + 5, // goto_w + 5, // jsr_w + + }; + + /** + * Bytecode names (for debugging/printing) + */ + public static final String JBC_name[] = + { + "nop", + "aconst_null", + "iconst_m1", + "iconst_0", + "iconst_1", + "iconst_2", + "iconst_3", + "iconst_4", + "iconst_5", + "lconst_0", + "lconst_1", + "fconst_0", + "fconst_1", + "fconst_2", + "dconst_0", + "dconst_1", + "bipush", + "sipush", + "ldc", + "ldc_w", + "ldc2_w", + "iload", + "lload", + "fload", + "dload", + "aload", + "iload_0", + "iload_1", + "iload_2", + "iload_3", + "lload_0", + "lload_1", + "lload_2", + "lload_3", + "fload_0", + "fload_1", + "fload_2", + " fload_3", + " dload_0", + " dload_1", + " dload_2", + " dload_3", + " aload_0", + " aload_1", + " aload_2", + " aload_3", + " iaload", + " laload", + " faload", + " daload", + " aaload", + " baload", + " caload", + " saload", + " istore", + " lstore", + " fstore", + " dstore", + " astore", + " istore_0", + " istore_1", + " istore_2", + " istore_3", + " lstore_0", + " lstore_1", + " lstore_2", + " lstore_3", + " fstore_0", + " fstore_1", + " fstore_2", + " fstore_3", + " dstore_0", + " dstore_1", + " dstore_2", + " dstore_3", + " astore_0", + " astore_1", + " astore_2", + " astore_3", + "iastore", + "lastore", + "fastore", + "dastore", + "aastore", + "bastore", + "castore", + "sastore", + "pop", + "pop2", + "dup", + "dup_x1", + "dup_x2", + "dup2", + "dup2_x1", + "dup2_x2", + "swap", + "iadd", + "ladd", + "fadd", + "dadd", + "isub", + "lsub", + "fsub", + "dsub", + "imul", + "lmul", + "fmul", + "dmul", + "idiv", + "ldiv", + "fdiv", + "ddiv", + "irem", + "lrem", + "frem", + "drem", + "ineg", + "lneg", + "fneg", + "dneg", + "ishl", + "lshl", + "ishr", + "lshr", + "iushr", + "lushr", + "iand", + "land", + "ior", + "lor", + "ixor", + "lxor", + "iinc", + "i2l", + "i2f", + "i2d", + "l2i", + "l2f", + "l2d", + "f2i", + "f2l", + "f2d", + "d2i", + "d2l", + "d2f", + "int2byte", + "int2char", + "int2short", + "lcmp", + "fcmpl", + "fcmpg", + "dcmpl", + "dcmpg", + "ifeq", + "ifne", + "iflt", + "ifge", + "ifgt", + "ifle", + "if_icmpeq", + "if_icmpne", + "if_icmplt", + "if_icmpge", + "if_icmpgt", + "if_icmple", + "if_acmpeq", + "if_acmpne", + "goto", + "jsr", + "ret", + " tableswitch", + " lookupswitch", + "ireturn", + "lreturn", + "freturn", + "dreturn", + "areturn", + "return", + "getstatic", + "putstatic", + "getfield", + "putfield", + "invokevirtual", + "invokenonvirtual", + "invokestatic", + "invokeinterface", + " xxxunusedxxx", + "new", + "newarray", + "anewarray", + "arraylength", + "athrow", + "checkcast", + "instanceof", + "monitorenter", + "monitorexit", + " wide", + "multianewarray", + "ifnull", + "ifnonnull", + "goto_w", + "jsr_w", + }; + +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/CheckCastInstruction.java b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/CheckCastInstruction.java new file mode 100644 index 000000000..a1efc9278 --- /dev/null +++ b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/CheckCastInstruction.java @@ -0,0 +1,73 @@ +/******************************************************************************* + * 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.shrikeBT; + +/** + * This class represents checkcast instructions. + */ +final public class CheckCastInstruction extends Instruction { + private String type; + + protected CheckCastInstruction(String type) { + this.type = type; + this.opcode = OP_checkcast; + } + + public static CheckCastInstruction make(String type) { + return new CheckCastInstruction(type.intern()); + } + + public boolean equals(Object o) { + if (o instanceof CheckCastInstruction) { + CheckCastInstruction i = (CheckCastInstruction) o; + return i.type.equals(type); + } else { + return false; + } + } + + public int hashCode() { + return 131111 + type.hashCode(); + } + + public int getPoppedCount() { + return 1; + } + + /** + * @return the type to which the operand is cast + */ + public String getType() { + return type; + } + + public String getPushedType(String[] types) { + return type; + } + + public byte getPushedWordSize() { + return 1; + } + + public void visit(Visitor v) { + v.visitCheckCast(this); + } + + public String toString() { + return "CheckCast(" + type + ")"; + } + /* (non-Javadoc) + * @see com.ibm.domo.cfg.IInstruction#isPEI() + */ + public boolean isPEI() { + return true; + } +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/ComparisonInstruction.java b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/ComparisonInstruction.java new file mode 100644 index 000000000..385585b67 --- /dev/null +++ b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/ComparisonInstruction.java @@ -0,0 +1,133 @@ +/******************************************************************************* + * 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.shrikeBT; + +/** + * This class represents comparisons between floats, longs and doubles. + */ +final public class ComparisonInstruction extends Instruction { + public enum Operator { + CMP, CMPL, CMPG; + + @Override + public String toString() { + return super.toString().toLowerCase(); + } + } + + protected ComparisonInstruction(short opcode) { + this.opcode = opcode; + } + + private final static ComparisonInstruction preallocatedLCMP = new ComparisonInstruction((short) OP_lcmp); + private final static ComparisonInstruction[] preallocatedFloatingCompares = preallocateFloatingCompares(); + + private static ComparisonInstruction[] preallocateFloatingCompares() { + ComparisonInstruction[] r = new ComparisonInstruction[OP_dcmpg - OP_fcmpl + 1]; + for (short i = OP_fcmpl; i <= OP_dcmpg; i++) { + r[i - OP_fcmpl] = new ComparisonInstruction(i); + } + return r; + } + + public static ComparisonInstruction make(String type, Operator operator) { + int t = Util.getTypeIndex(type); + switch (t) { + case TYPE_long_index: + if (operator != Operator.CMP) { + throw new IllegalArgumentException("Operator " + operator + " is not a valid comparison operator for longs"); + } else { + return preallocatedLCMP; + } + case TYPE_float_index: + case TYPE_double_index: + if (operator == Operator.CMP) { + throw new IllegalArgumentException("Operator " + operator + " is not a valid comparison operator for floating point values"); + } else { + return preallocatedFloatingCompares[(operator.ordinal() - Operator.CMPL.ordinal()) + (t - TYPE_float_index) * 2]; + } + default: + throw new IllegalArgumentException("Type " + type + " cannot be compared"); + } + } + + public boolean equals(Object o) { + if (o instanceof ComparisonInstruction) { + ComparisonInstruction i = (ComparisonInstruction) o; + return i.opcode == opcode; + } else { + return false; + } + } + + /** + * @return OPR_cmp (for long), OPR_cmpl, or OPR_cmpg (for float and double) + */ + public Operator getOperator() { + switch (opcode) { + case OP_lcmp: + return Operator.CMP; + case OP_fcmpl: + case OP_dcmpl: + return Operator.CMPL; + case OP_dcmpg: + case OP_fcmpg: + return Operator.CMPG; + default: + throw new Error("Unknown opcode"); + } + } + + public String getType() { + switch (opcode) { + case OP_lcmp: + return TYPE_long; + case OP_fcmpg: + case OP_fcmpl: + return TYPE_float; + case OP_dcmpl: + case OP_dcmpg: + return TYPE_double; + default: + throw new Error("Unknown opcode"); + } + } + + public int hashCode() { + return opcode + 1391901; + } + + public int getPoppedCount() { + return 2; + } + + public String getPushedType(String[] types) { + return Constants.TYPE_boolean; + } + + public byte getPushedWordSize() { + return 1; + } + + public void visit(Visitor v) { + v.visitComparison(this); + } + + public String toString() { + return "Comparison(" + getType() + "," + getOperator() + ")"; + } + /* (non-Javadoc) + * @see com.ibm.domo.cfg.IInstruction#isPEI() + */ + public boolean isPEI() { + return false; + } +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/Compiler.java b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/Compiler.java new file mode 100644 index 000000000..863f03207 --- /dev/null +++ b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/Compiler.java @@ -0,0 +1,1799 @@ +/******************************************************************************* + * 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.shrikeBT; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.BitSet; +import java.util.Iterator; + +import com.ibm.wala.shrikeBT.BinaryOpInstruction.Operator; +import com.ibm.wala.shrikeBT.analysis.ClassHierarchyProvider; +import com.ibm.wala.shrikeBT.analysis.Verifier; + +/** + * This class generates Java bytecode from ShrikeBT Instructions. + * + * If there are too many instructions to fit into 64K bytecodes, then we break + * the method up, generating auxiliary methods called by the main method. + * + * This class is abstract; there are subclasses for specific class file access + * toolkits. These toolkits are responsible for providing ways to allocate + * constant pool entries. + */ +public abstract class Compiler implements Constants { + // input + private boolean isStatic; + private String classType; + private String signature; + private Instruction[] instructions; + private ExceptionHandler[][] handlers; + private int[] instructionsToBytecodes; + + private static final int[] noRawHandlers = new int[0]; + + private ClassHierarchyProvider hierarchy; + private ConstantPoolReader presetConstants; + + // working + private int[] instructionsToOffsets; + private BitSet branchTargets; + private byte[][] stackWords; + private byte[] code; + + // working on breaking up overlarge methods + private int allocatedLocals; + private BitSet[] liveLocals; + private int[][] backEdges; + private String[][] localTypes; + private String[][] stackTypes; + + // output + private int maxLocals; + private int maxStack; + private Output mainMethod; + private ArrayList auxMethods; + + /** + * Initialize a Compiler for the given method data. + * + * @param isStatic + * true iff the method is static + * @param classType + * the JVM type of the class the method belongs to + * @param signature + * the JVM signature of the method + * @param instructions + * the ShrikeBT instructions + * @param handlers + * the ShrikeBT exception handlers + * @param instructionsToBytecodes + * the map from instructions to original bytecode offsets + */ + public Compiler(boolean isStatic, String classType, String signature, Instruction[] instructions, ExceptionHandler[][] handlers, + int[] instructionsToBytecodes) { + if (instructions.length != handlers.length) { + throw new IllegalArgumentException("Instructions/handlers length mismatch"); + } + if (instructions.length != instructionsToBytecodes.length) { + throw new IllegalArgumentException("Instructions/handlers length mismatch"); + } + + this.isStatic = isStatic; + this.classType = classType; + this.signature = signature; + this.instructions = instructions; + this.handlers = handlers; + this.instructionsToBytecodes = instructionsToBytecodes; + } + + /** + * Extract the data for the method to be compiled from the MethodData + * container. + */ + public Compiler(MethodData info) { + this(info.getIsStatic(), info.getClassType(), info.getSignature(), info.getInstructions(), info.getHandlers(), info + .getInstructionsToBytecodes()); + } + + /** + * @return the JVM type for the class this method belongs to + */ + final public String getClassType() { + return classType; + } + + /** + * Notify the compiler that the constants appearing in the ConstantPoolReader + * cp will appear in the final class file. + * + * Instructions which were extracted from a class file with the same + * ConstantPoolReader can be written back much more efficiently if the same + * constant pool indices are valid in the new class file. + */ + final public void setPresetConstants(ConstantPoolReader cp) { + presetConstants = cp; + } + + final public void setClassHierarchy(ClassHierarchyProvider h) { + this.hierarchy = h; + } + + protected abstract int allocateConstantPoolInteger(int v); + + protected abstract int allocateConstantPoolFloat(float v); + + protected abstract int allocateConstantPoolLong(long v); + + protected abstract int allocateConstantPoolDouble(double v); + + protected abstract int allocateConstantPoolString(String v); + + protected abstract int allocateConstantPoolClassType(String c); + + protected abstract int allocateConstantPoolField(String c, String name, String type); + + protected abstract int allocateConstantPoolMethod(String c, String name, String sig); + + protected abstract int allocateConstantPoolInterfaceMethod(String c, String name, String sig); + + protected abstract String createHelperMethod(boolean isStatic, String sig); + + private void collectInstructionInfo() { + final BitSet s = new BitSet(instructions.length); + final BitSet localsUsed = new BitSet(32); + final BitSet localsWide = new BitSet(32); + + Instruction.Visitor visitor = new Instruction.Visitor() { + private void visitTargets(Instruction instr) { + int[] ts = instr.getBranchTargets(); + for (int k = 0; k < ts.length; k++) { + s.set(ts[k]); + } + } + + public void visitGoto(GotoInstruction instruction) { + visitTargets(instruction); + } + + public void visitLocalStore(StoreInstruction instruction) { + localsUsed.set(instruction.getVarIndex()); + String t = instruction.getType(); + if (t.equals(TYPE_long) || t.equals(TYPE_double)) { + localsWide.set(instruction.getVarIndex()); + } + } + + public void visitConditionalBranch(ConditionalBranchInstruction instruction) { + visitTargets(instruction); + } + + public void visitSwitch(SwitchInstruction instruction) { + visitTargets(instruction); + } + }; + + for (int i = 0; i < instructions.length; i++) { + instructions[i].visit(visitor); + } + + String[] paramTypes = Util.getParamsTypes(isStatic ? null : TYPE_Object, signature); + int index = 0; + for (int i = 0; i < paramTypes.length; i++) { + String t = paramTypes[i]; + localsUsed.set(index); + if (t.equals(TYPE_long) || t.equals(TYPE_double)) { + localsWide.set(index); + index += 2; + } else { + index++; + } + } + + ExceptionHandler[] lastHS = null; + for (int i = 0; i < handlers.length; i++) { + ExceptionHandler[] hs = handlers[i]; + if (hs != lastHS) { + for (int j = 0; j < hs.length; j++) { + s.set(hs[j].handler); + } + lastHS = hs; + } + } + + this.branchTargets = s; + + int maxUsed = localsUsed.length(); + if (maxUsed > 0 && localsWide.get(maxUsed - 1)) { + maxUsed++; + } + this.maxLocals = maxUsed; + } + + private void writeInt(int offset, int v) { + code[offset] = (byte) (v >> 24); + code[offset + 1] = (byte) (v >> 16); + code[offset + 2] = (byte) (v >> 8); + code[offset + 3] = (byte) v; + } + + private void writeShort(int offset, int v) { + code[offset] = (byte) (v >> 8); + code[offset + 1] = (byte) v; + } + + private void writeByte(int offset, int v) { + code[offset] = (byte) v; + } + + private boolean inBasicBlock(int i, int n) { + if (i + n - 1 >= instructions.length) { + return false; + } + + for (int j = i + 1; j < i + n; j++) { + if (branchTargets.get(j)) { + return false; + } + + if (!Arrays.equals(handlers[j], handlers[i])) { + return false; + } + + if (instructionsToBytecodes[j] != instructionsToBytecodes[i]) { + return false; + } + } + + return true; + } + + private void checkStackWordSize(byte[] stackWords, int stackLen) { + if (stackLen * 2 > maxStack) { + int words = 0; + for (int i = 0; i < stackLen; i++) { + words += stackWords[i]; + } + if (words > maxStack) { + maxStack = words; + } + } + } + +// private static int getStackDelta(Instruction instr) { +// if (instr instanceof DupInstruction) { +// return ((DupInstruction) instr).getSize(); +// } else { +// return (instr.getPushedWordSize() > 0 ? 1 : 0) - instr.getPoppedCount(); +// } +// } + + private void computeStackWordsAt(int i, int stackLen, byte[] stackWords, boolean[] visited) { + while (!visited[i]) { + Instruction instr = instructions[i]; + + if (i > 0 && !instructions[i - 1].isFallThrough()) { + byte[] newWords = new byte[stackLen]; + System.arraycopy(stackWords, 0, newWords, 0, stackLen); + this.stackWords[i] = newWords; + } + + visited[i] = true; + + if (stackLen < instr.getPoppedCount()) { + throw new IllegalArgumentException("Stack underflow in intermediate code, at offset " + i); + } + + if (instr instanceof DupInstruction) { + DupInstruction d = (DupInstruction) instr; + int size = d.getSize(); + int delta = d.getDelta(); + + System.arraycopy(stackWords, stackLen - size - delta, stackWords, stackLen - delta, delta + size); + System.arraycopy(stackWords, stackLen, stackWords, stackLen - size - delta, size); + stackLen += size; + checkStackWordSize(stackWords, stackLen); + } else if (instr instanceof SwapInstruction) { + // we may have to emulate this using a dup[2]_x[1,2] + // followed by a pop[2]. So update the maxStack to account for the + // temporarily larger stack size + int words = stackWords[stackLen - 1]; + for (int j = 0; j < stackLen; j++) { + words += stackWords[j]; + } + if (words > maxStack) { + maxStack = words; + } + + byte b = stackWords[stackLen - 2]; + stackWords[stackLen - 2] = stackWords[stackLen - 1]; + stackWords[stackLen - 1] = b; + } else { + stackLen -= instr.getPoppedCount(); + + byte w = instr.getPushedWordSize(); + if (w > 0) { + stackWords[stackLen] = w; + stackLen++; + checkStackWordSize(stackWords, stackLen); + } + } + + int[] bt = instr.getBranchTargets(); + for (int j = 0; j < bt.length; j++) { + int t = bt[j]; + if (t < 0 || t >= visited.length) { + throw new IllegalArgumentException("Branch target at offset " + i + " is out of bounds: " + t + " (max " + visited.length + + ")"); + } + if (!visited[t]) { + computeStackWordsAt(bt[j], stackLen, (byte[]) stackWords.clone(), visited); + } + } + + ExceptionHandler[] hs = handlers[i]; + for (int j = 0; j < hs.length; j++) { + int t = hs[j].handler; + if (!visited[t]) { + byte[] newWords = (byte[]) stackWords.clone(); + newWords[0] = 1; + computeStackWordsAt(t, 1, newWords, visited); + } + } + + if (!instr.isFallThrough()) { + return; + } + + i++; + } + } + + private void computeStackWords() { + stackWords = new byte[instructions.length][]; + maxStack = 0; + + computeStackWordsAt(0, 0, new byte[instructions.length * 2], new boolean[instructions.length]); + } + + abstract class Patch { + int instrStart; + int instrOffset; + int targetLabel; + + Patch(int instrStart, int instrOffset, int targetLabel) { + this.instrStart = instrStart; + this.instrOffset = instrOffset; + this.targetLabel = targetLabel; + } + + abstract boolean apply(); + } + + class ShortPatch extends Patch { + ShortPatch(int instrStart, int instrOffset, int targetLabel) { + super(instrStart, instrOffset, targetLabel); + } + + boolean apply() { + int delta = instructionsToOffsets[targetLabel] - instrStart; + if ((short) delta == delta) { + writeShort(instrOffset, delta); + return true; + } else { + return false; + } + } + } + + class IntPatch extends Patch { + IntPatch(int instrStart, int instrOffset, int targetLabel) { + super(instrStart, instrOffset, targetLabel); + } + + boolean apply() { + writeInt(instrOffset, instructionsToOffsets[targetLabel] - instrStart); + return true; + } + } + + private void insertBranchOffsetInt(ArrayList patches, int instrStart, int instrOffset, int targetLabel) { + if (instructionsToOffsets[targetLabel] > 0 || targetLabel == 0) { + writeInt(instrOffset, instructionsToOffsets[targetLabel] - instrStart); + } else { + patches.add(new IntPatch(instrStart, instrOffset, targetLabel)); + } + } + + private boolean applyPatches(ArrayList patches) { + for (Iterator i = patches.iterator(); i.hasNext();) { + Patch p = i.next(); + if (!p.apply()) { + return false; + } + } + return true; + } + + private static byte[] cachedBuf; + + private static synchronized byte[] makeCodeBuf() { + if (cachedBuf != null) { + byte[] result = cachedBuf; + cachedBuf = null; + return result; + } else { + return new byte[65535]; + } + } + + private static synchronized void releaseCodeBuf(byte[] buf) { + cachedBuf = buf; + } + + private boolean outputInstructions(int startInstruction, int endInstruction, int startOffset, boolean farBranches, + byte[] initialStack) { + instructionsToOffsets = new int[instructions.length]; + code = makeCodeBuf(); + + ArrayList patches = new ArrayList(); + + int curOffset = startOffset; + final int[] curOffsetRef = new int[1]; + int stackLen = initialStack == null ? 0 : initialStack.length; + final int[] stackLenRef = new int[1]; + final byte[] stackWords = new byte[maxStack]; + if (stackLen > 0) { + System.arraycopy(initialStack, 0, stackWords, 0, stackLen); + } + final int[] instrRef = new int[1]; + + Instruction.Visitor noOpcodeHandler = new Instruction.Visitor() { + public void visitPop(PopInstruction instruction) { + int count = instruction.getPoppedCount(); + int offset = curOffsetRef[0]; + int stackLen = stackLenRef[0]; + + while (count > 0) { + code[offset] = (byte) (stackWords[stackLen - 1] == 1 ? OP_pop : OP_pop2); + count--; + stackLen--; + offset++; + } + + curOffsetRef[0] = offset; + } + + public void visitDup(DupInstruction instruction) { + int size = instruction.getSize(); + int delta = instruction.getDelta(); + int offset = curOffsetRef[0]; + int stackLen = stackLenRef[0]; + + int sizeWords = stackWords[stackLen - 1]; + if (size == 2) { + sizeWords += stackWords[stackLen - 2]; + } + int deltaWords = delta == 0 ? 0 : stackWords[stackLen - 1 - size]; + if (delta == 2) { + deltaWords += stackWords[stackLen - 1 - size - 1]; + } + if (sizeWords > 2 || deltaWords > 2) { + throw new IllegalArgumentException("Invalid dup size"); + } + + code[offset] = (byte) (OP_dup + (3 * (sizeWords - 1)) + deltaWords); + offset++; + curOffsetRef[0] = offset; + } + + public void visitSwap(SwapInstruction instruction) { + int offset = curOffsetRef[0]; + int stackLen = stackLenRef[0]; + int topSize = stackWords[stackLen - 1]; + int nextSize = stackWords[stackLen - 2]; + + if (topSize == 1 && nextSize == 1) { + code[offset] = (byte) OP_swap; + offset++; + } else { + code[offset] = (byte) (OP_dup + (3 * (topSize - 1)) + nextSize); + code[offset + 1] = (byte) (topSize == 1 ? OP_pop : OP_pop2); + offset += 2; + } + + curOffsetRef[0] = offset; + } + }; + + for (int i = startInstruction; i < endInstruction; i++) { + Instruction instr = instructions[i]; + int opcode = instr.getOpcode(); + int startI = i; + + instructionsToOffsets[i] = curOffset; + + if (opcode != -1) { + boolean fallToConditional = false; + + code[curOffset] = (byte) opcode; + curOffset++; + + switch (opcode) { + case OP_iconst_0: + if (inBasicBlock(i, 2) && instructions[i + 1] instanceof ConditionalBranchInstruction) { + ConditionalBranchInstruction cbr = (ConditionalBranchInstruction) instructions[i + 1]; + if (cbr.getType().equals(TYPE_int)) { + code[curOffset - 1] = (byte) (cbr.getOperator().ordinal() + OP_ifeq); + fallToConditional = true; + i++; + instr = instructions[i]; + } + } + if (!fallToConditional) { + break; + } + case OP_aconst_null: + if (!fallToConditional && inBasicBlock(i, 2) && instructions[i + 1] instanceof ConditionalBranchInstruction) { + ConditionalBranchInstruction cbr = (ConditionalBranchInstruction) instructions[i + 1]; + if (cbr.getType().equals(TYPE_Object)) { + code[curOffset - 1] = (byte) (cbr.getOperator().ordinal() + OP_ifnull); + fallToConditional = true; + i++; + instr = instructions[i]; + } + } + if (!fallToConditional) { + break; + } + //by Xiangyu + case OP_ifeq: + case OP_ifge: + case OP_ifgt: + case OP_ifle: + case OP_iflt: + case OP_ifne: { + int targetI = instr.getBranchTargets()[0]; + boolean invert = false; + int iStart = curOffset - 1; + + if (inBasicBlock(i, 2) && instr.getBranchTargets()[0] == i + 2 && instructions[i + 1] instanceof GotoInstruction) { + invert = true; + targetI = instructions[i + 1].getBranchTargets()[0]; + i++; + } + + if (targetI <= i) { + int delta = instructionsToOffsets[targetI] - iStart; + if ((short) delta != delta) { + // emit "if_!XX TMP; goto_w L; TMP:" + invert = !invert; + writeShort(curOffset, 8); + code[curOffset + 2] = (byte) OP_goto_w; + writeInt(curOffset + 3, delta - 3); + curOffset += 7; + } else { + writeShort(curOffset, (short) delta); + curOffset += 2; + } + } else { + Patch p; + if (farBranches) { + // emit "if_!XX TMP; goto_w L; TMP:" + invert = !invert; + writeShort(curOffset, 8); + code[curOffset + 2] = (byte) OP_goto_w; + p = new IntPatch(curOffset + 2, curOffset + 3, targetI); + curOffset += 7; + } else { + p = new ShortPatch(iStart, curOffset, targetI); + curOffset += 2; + } + patches.add(p); + } + + if (invert) { + code[iStart] = (byte) (((code[iStart] - OP_ifeq) ^ 1) + OP_ifeq); + } + break; + } + //by Xiangyu + + case OP_if_icmpeq: + case OP_if_icmpge: + case OP_if_icmpgt: + case OP_if_icmple: + case OP_if_icmplt: + case OP_if_icmpne: + case OP_if_acmpeq: + case OP_if_acmpne: { + int targetI = instr.getBranchTargets()[0]; + boolean invert = false; + int iStart = curOffset - 1; + + if (inBasicBlock(i, 2) && instr.getBranchTargets()[0] == i + 2 && instructions[i + 1] instanceof GotoInstruction) { + invert = true; + targetI = instructions[i + 1].getBranchTargets()[0]; + i++; + } + + if (targetI <= i) { + int delta = instructionsToOffsets[targetI] - iStart; + if ((short) delta != delta) { + // emit "if_!XX TMP; goto_w L; TMP:" + invert = !invert; + writeShort(curOffset, 8); + code[curOffset + 2] = (byte) OP_goto_w; + writeInt(curOffset + 3, delta - 3); + curOffset += 7; + } else { + writeShort(curOffset, (short) delta); + curOffset += 2; + } + } else { + Patch p; + if (farBranches) { + // emit "if_!XX TMP; goto_w L; TMP:" + invert = !invert; + writeShort(curOffset, 8); + code[curOffset + 2] = (byte) OP_goto_w; + p = new IntPatch(curOffset + 2, curOffset + 3, targetI); + curOffset += 7; + } else { + p = new ShortPatch(iStart, curOffset, targetI); + curOffset += 2; + } + patches.add(p); + } + + if (invert) { + code[iStart] = (byte) (((code[iStart] - OP_if_icmpeq) ^ 1) + OP_if_icmpeq); + } + break; + } + case OP_bipush: + writeByte(curOffset, ((ConstantInstruction.ConstInt) instr).getIntValue()); + curOffset++; + break; + case OP_sipush: + writeShort(curOffset, ((ConstantInstruction.ConstInt) instr).getIntValue()); + curOffset += 2; + break; + case OP_ldc_w: { + int cpIndex; + ConstantInstruction ci = (ConstantInstruction) instr; + if (presetConstants != null && ci.getLazyConstantPool() == presetConstants) { + cpIndex = ci.getCPIndex(); + } else { + String t = instr.getPushedType(null); + if (t.equals(TYPE_int)) { + cpIndex = allocateConstantPoolInteger(((ConstantInstruction.ConstInt) instr).getIntValue()); + } else if (t.equals(TYPE_String)) { + cpIndex = allocateConstantPoolString((String) ((ConstantInstruction.ConstString) instr).getValue()); + } else { + cpIndex = allocateConstantPoolFloat(((ConstantInstruction.ConstFloat) instr).getFloatValue()); + } + } + + if (cpIndex < 256) { + code[curOffset - 1] = (byte) OP_ldc; + code[curOffset] = (byte) cpIndex; + curOffset++; + } else { + writeShort(curOffset, cpIndex); + curOffset += 2; + } + break; + } + case OP_ldc2_w: { + int cpIndex; + ConstantInstruction ci = (ConstantInstruction) instr; + if (presetConstants != null && ci.getLazyConstantPool() == presetConstants) { + cpIndex = ci.getCPIndex(); + } else { + String t = instr.getPushedType(null); + if (t.equals(TYPE_long)) { + cpIndex = allocateConstantPoolLong(((ConstantInstruction.ConstLong) instr).getLongValue()); + } else { + cpIndex = allocateConstantPoolDouble(((ConstantInstruction.ConstDouble) instr).getDoubleValue()); + } + } + + writeShort(curOffset, cpIndex); + curOffset += 2; + break; + } + case OP_iload_0: + case OP_iload_1: + case OP_iload_2: + case OP_iload_3: + case OP_iload: { + if (inBasicBlock(i, 4)) { + // try to generate an OP_iinc + if (instructions[i + 1] instanceof ConstantInstruction.ConstInt && instructions[i + 2] instanceof BinaryOpInstruction + && instructions[i + 3] instanceof StoreInstruction) { + LoadInstruction i0 = (LoadInstruction) instr; + ConstantInstruction.ConstInt i1 = (ConstantInstruction.ConstInt) instructions[i + 1]; + BinaryOpInstruction i2 = (BinaryOpInstruction) instructions[i + 2]; + StoreInstruction i3 = (StoreInstruction) instructions[i + 3]; + + int c = i1.getIntValue(); + int v = i0.getVarIndex(); + BinaryOpInstruction.Operator op = i2.getOperator(); + if ((short) c == c && i3.getVarIndex() == v && (op == Operator.ADD || op == Operator.SUB) && i2.getType().equals(TYPE_int) + && i3.getType().equals(TYPE_int)) { + if (v < 256 && (byte) c == c) { + code[curOffset - 1] = (byte) OP_iinc; + writeByte(curOffset, v); + writeByte(curOffset + 1, c); + curOffset += 2; + } else { + code[curOffset - 1] = (byte) OP_wide; + code[curOffset] = (byte) OP_iinc; + writeShort(curOffset + 1, v); + writeShort(curOffset + 3, c); + curOffset += 5; + } + instructionsToOffsets[i + 1] = -1; + instructionsToOffsets[i + 2] = -1; + instructionsToOffsets[i + 3] = -1; + i += 3; + break; + } + } + } + if (opcode != OP_iload) { + break; + } + } + case OP_lload: + case OP_fload: + case OP_dload: + case OP_aload: { + int v = ((LoadInstruction) instr).getVarIndex(); + + if (v < 256) { + writeByte(curOffset, v); + curOffset++; + } else { + code[curOffset - 1] = (byte) OP_wide; + code[curOffset] = (byte) opcode; + writeShort(curOffset + 1, v); + curOffset += 3; + } + break; + } + case OP_istore: + case OP_lstore: + case OP_fstore: + case OP_dstore: + case OP_astore: { + int v = ((StoreInstruction) instr).getVarIndex(); + + if (v < 256) { + writeByte(curOffset, v); + curOffset++; + } else { + code[curOffset - 1] = (byte) OP_wide; + code[curOffset] = (byte) opcode; + writeShort(curOffset + 1, v); + curOffset += 3; + } + break; + } + case OP_goto: { + int targetI = instr.getBranchTargets()[0]; + if (targetI <= i) { + int delta = instructionsToOffsets[targetI] - (curOffset - 1); + if ((short) delta != delta) { + code[curOffset - 1] = (byte) OP_goto_w; + writeInt(curOffset, delta); + curOffset += 4; + } else { + writeShort(curOffset, (short) delta); + curOffset += 2; + } + } else if (targetI == i + 1) { + // ignore noop gotos + curOffset--; + } else { + Patch p; + if (farBranches) { + code[curOffset - 1] = (byte) OP_goto_w; + p = new IntPatch(curOffset - 1, curOffset, instr.getBranchTargets()[0]); + curOffset += 4; + } else { + p = new ShortPatch(curOffset - 1, curOffset, instr.getBranchTargets()[0]); + curOffset += 2; + } + patches.add(p); + } + break; + } + case OP_lookupswitch: { + int start = curOffset - 1; + SwitchInstruction sw = (SwitchInstruction) instr; + int[] casesAndLabels = sw.getCasesAndLabels(); + + while ((curOffset & 3) != 0) { + writeByte(curOffset, 0); + curOffset++; + } + + if (curOffset + 4 * casesAndLabels.length + 8 > code.length) { + return false; + } + insertBranchOffsetInt(patches, start, curOffset, sw.getDefaultLabel()); + writeInt(curOffset + 4, casesAndLabels.length / 2); + curOffset += 8; + for (int j = 0; j < casesAndLabels.length; j += 2) { + writeInt(curOffset, casesAndLabels[j]); + insertBranchOffsetInt(patches, start, curOffset + 4, casesAndLabels[j + 1]); + curOffset += 8; + } + break; + } + case OP_tableswitch: { + int start = curOffset - 1; + SwitchInstruction sw = (SwitchInstruction) instr; + int[] casesAndLabels = sw.getCasesAndLabels(); + + while ((curOffset & 3) != 0) { + writeByte(curOffset, 0); + curOffset++; + } + if (curOffset + 2 * casesAndLabels.length + 12 > code.length) { + return false; + } + insertBranchOffsetInt(patches, start, curOffset, sw.getDefaultLabel()); + writeInt(curOffset + 4, casesAndLabels[0]); + writeInt(curOffset + 8, casesAndLabels[casesAndLabels.length - 2]); + curOffset += 12; + for (int j = 0; j < casesAndLabels.length; j += 2) { + insertBranchOffsetInt(patches, start, curOffset, casesAndLabels[j + 1]); + curOffset += 4; + } + break; + } + case OP_getfield: + case OP_getstatic: { + GetInstruction g = (GetInstruction) instr; + int cpIndex; + + if (presetConstants != null && presetConstants == g.getLazyConstantPool()) { + cpIndex = ((GetInstruction.Lazy) g).getCPIndex(); + } else { + cpIndex = allocateConstantPoolField(g.getClassType(), g.getFieldName(), g.getFieldType()); + } + writeShort(curOffset, cpIndex); + curOffset += 2; + break; + } + case OP_putfield: + case OP_putstatic: { + PutInstruction p = (PutInstruction) instr; + int cpIndex; + + if (presetConstants != null && presetConstants == p.getLazyConstantPool()) { + cpIndex = ((PutInstruction.Lazy) p).getCPIndex(); + } else { + cpIndex = allocateConstantPoolField(p.getClassType(), p.getFieldName(), p.getFieldType()); + } + writeShort(curOffset, cpIndex); + curOffset += 2; + break; + } + case OP_invokespecial: + case OP_invokestatic: + case OP_invokevirtual: { + InvokeInstruction inv = (InvokeInstruction) instr; + int cpIndex; + + if (presetConstants != null && presetConstants == inv.getLazyConstantPool()) { + cpIndex = ((InvokeInstruction.Lazy) inv).getCPIndex(); + } else { + cpIndex = allocateConstantPoolMethod(inv.getClassType(), inv.getMethodName(), inv.getMethodSignature()); + } + writeShort(curOffset, cpIndex); + curOffset += 2; + break; + } + case OP_invokeinterface: { + InvokeInstruction inv = (InvokeInstruction) instr; + String sig = inv.getMethodSignature(); + int cpIndex; + + if (presetConstants != null && presetConstants == inv.getLazyConstantPool()) { + cpIndex = ((InvokeInstruction.Lazy) inv).getCPIndex(); + } else { + cpIndex = allocateConstantPoolInterfaceMethod(inv.getClassType(), inv.getMethodName(), sig); + } + writeShort(curOffset, cpIndex); + code[curOffset + 2] = (byte) (Util.getParamsWordSize(sig) + 1); + code[curOffset + 3] = 0; + curOffset += 4; + break; + } + case OP_new: + writeShort(curOffset, allocateConstantPoolClassType(((NewInstruction) instr).getType())); + curOffset += 2; + break; + case OP_newarray: + code[curOffset] = indexedTypes_T[Util.getTypeIndex(((NewInstruction) instr).getType().substring(1))]; + curOffset++; + break; + case OP_anewarray: + writeShort(curOffset, allocateConstantPoolClassType(((NewInstruction) instr).getType().substring(1))); + curOffset += 2; + break; + case OP_multianewarray: { + NewInstruction n = (NewInstruction) instr; + writeShort(curOffset, allocateConstantPoolClassType(n.getType())); + code[curOffset + 2] = (byte) n.getArrayBoundsCount(); + curOffset += 3; + break; + } + case OP_checkcast: + writeShort(curOffset, allocateConstantPoolClassType(((CheckCastInstruction) instr).getType())); + curOffset += 2; + break; + case OP_instanceof: + writeShort(curOffset, allocateConstantPoolClassType(((InstanceofInstruction) instr).getType())); + curOffset += 2; + break; + } + } else { + stackLenRef[0] = stackLen; + curOffsetRef[0] = curOffset; + instrRef[0] = i; + instr.visit(noOpcodeHandler); + curOffset = curOffsetRef[0]; + i = instrRef[0]; + } + + boolean haveStack = true; + + while (startI <= i) { + instr = instructions[startI]; + if (instr.isFallThrough() && haveStack) { + if (stackLen < instr.getPoppedCount()) { + throw new IllegalArgumentException("Stack underflow in intermediate code, at offset " + startI); + } + + if (instr instanceof DupInstruction) { + DupInstruction d = (DupInstruction) instr; + int size = d.getSize(); + int delta = d.getDelta(); + + System.arraycopy(stackWords, stackLen - size - delta, stackWords, stackLen - delta, delta + size); + System.arraycopy(stackWords, stackLen, stackWords, stackLen - size - delta, size); + stackLen += size; + } else if (instr instanceof SwapInstruction) { + byte b = stackWords[stackLen - 1]; + stackWords[stackLen - 1] = stackWords[stackLen - 2]; + stackWords[stackLen - 2] = b; + } else { + stackLen -= instr.getPoppedCount(); + + byte w = instr.getPushedWordSize(); + if (w > 0) { + stackWords[stackLen] = w; + stackLen++; + } + } + } else { + // No stack, or the instruction doesn't fall through + // try to grab the stack state at the start of the next instruction + if (startI + 1 < endInstruction) { + byte[] s = this.stackWords[startI + 1]; + // if the next instruction doesn't have stack info (it's not + // reachable), then just ignore it and remember that we don't have + // stack info + if (s == null) { + haveStack = false; + } else { + stackLen = s.length; + System.arraycopy(s, 0, stackWords, 0, stackLen); + } + } + } + + startI++; + } + + if (curOffset > code.length - 8) { + return false; + } + + if (!haveStack) { + // skip forward through the unreachable instructions until we find + // an instruction for which we know the stack state + while (i + 1 < endInstruction) { + byte[] s = this.stackWords[i + 1]; + if (s != null) { + stackLen = s.length; + System.arraycopy(s, 0, stackWords, 0, stackLen); + break; + } + i++; + } + } + } + + if (applyPatches(patches)) { + byte[] newCode = new byte[curOffset]; + System.arraycopy(code, 0, newCode, 0, curOffset); + releaseCodeBuf(code); + code = newCode; + } else { + if (farBranches) { + throw new Error("Failed to apply patches even with farBranches on"); + } else { + return outputInstructions(startInstruction, endInstruction, startOffset, true, initialStack); + } + } + + return true; + } + + private int[] buildRawHandlers(int start, int end) { + int[] handlerCounts = new int[end - start]; + int maxCount = 0; + + for (int i = start; i < end; i++) { + int len = handlers[i].length; + handlerCounts[i - start] = len; + if (len > maxCount) { + maxCount = len; + } + } + + if (maxCount == 0) { + return noRawHandlers; + } else { + ArrayList rawHandlerList = new ArrayList(); + + for (int i = maxCount; i > 0; i--) { + for (int j = start; j < end; j++) { + if (handlerCounts[j - start] == i) { + int first = j; + ExceptionHandler h = handlers[j][handlers[j].length - i]; + + do { + handlerCounts[j - start]--; + j++; + } while (j < end && handlerCounts[j - start] == i && handlers[j][handlers[j].length - i].equals(h)); + + if (h.handler >= start && h.handler < end) { + rawHandlerList.add(new int[] { instructionsToOffsets[first], j < end ? instructionsToOffsets[j] : code.length, + instructionsToOffsets[h.handler], h.catchClass == null ? 0 : allocateConstantPoolClassType(h.catchClass) }); + } + + j--; + } + } + } + + int[] rawHandlers = new int[4 * rawHandlerList.size()]; + int count = 0; + for (Iterator iter = rawHandlerList.iterator(); iter.hasNext();) { + int[] element = iter.next(); + System.arraycopy(element, 0, rawHandlers, count, 4); + count += 4; + } + return rawHandlers; + } + } + + private int[] buildBytecodeMap(int start, int end) { + int[] r = new int[code.length]; + + for (int i = 0; i < r.length; i++) { + r[i] = -1; + } + + for (int i = start; i < end; i++) { + int off = instructionsToOffsets[i]; + if (off >= 0) { + r[off] = instructionsToBytecodes[i]; + } + } + + return r; + } + + static class HelperPatch { + int start; + int length; + Instruction[] code; + ExceptionHandler[] handlers; + + HelperPatch(int start, int length, Instruction[] code, ExceptionHandler[] handlers) { + this.start = start; + this.length = length; + this.code = code; + this.handlers = handlers; + } + } + + private void addBackEdge(int from, int to) { + int[] oldEdges = backEdges[from]; + if (oldEdges == null) { + backEdges[from] = new int[] { to }; + } else if (oldEdges[oldEdges.length - 1] < 0) { + int left = 1; + int right = oldEdges.length - 1; + while (true) { + if (right - left < 2) { + if (oldEdges[left] < 0) { + break; + } else { + if (oldEdges[right] >= 0) + throw new Error("Failed binary search"); + left = right; + break; + } + } else { + int mid = (left + right) / 2; + if (oldEdges[mid] < 0) { + right = mid; + } else { + left = mid + 1; + } + } + } + oldEdges[left] = to; + } else { + int[] newEdges = new int[oldEdges.length * 2]; + System.arraycopy(oldEdges, 0, newEdges, 0, oldEdges.length); + newEdges[oldEdges.length] = to; + for (int i = oldEdges.length + 1; i < newEdges.length; i++) { + newEdges[i] = -1; + } + backEdges[from] = newEdges; + } + } + + private void addLiveVar(int instruction, int index) { + while (true) { + if (liveLocals[instruction].get(index)) { + break; + } + + Instruction instr = instructions[instruction]; + if (instr instanceof StoreInstruction && ((StoreInstruction) instr).getVarIndex() == index) { + break; + } + + liveLocals[instruction].set(index); + int[] back = backEdges[instruction]; + if (back != null) { + for (int i = 0; i < back.length; i++) { + addLiveVar(back[i], index); + } + } + + if (instruction > 0 && instructions[instruction - 1].isFallThrough()) { + instruction--; + } else { + break; + } + } + } + + private void makeLiveLocals() { + liveLocals = new BitSet[instructions.length]; + backEdges = new int[instructions.length][]; + + for (int i = 0; i < instructions.length; i++) { + Instruction instr = instructions[i]; + int[] targets = instr.getBranchTargets(); + for (int j = 0; j < targets.length; j++) { + addBackEdge(targets[j], i); + } + ExceptionHandler[] hs = handlers[i]; + for (int j = 0; j < hs.length; j++) { + addBackEdge(hs[j].handler, i); + } + liveLocals[i] = new BitSet(); + } + + for (int i = 0; i < backEdges.length; i++) { + int[] back = backEdges[i]; + if (back != null && back[back.length - 1] < 0) { + int j = back.length; + while (back[j - 1] < 0) { + j--; + } + int[] newBack = new int[j]; + System.arraycopy(back, 0, newBack, 0, newBack.length); + backEdges[i] = newBack; + } + } + + for (int i = 0; i < instructions.length; i++) { + Instruction instr = instructions[i]; + if (instr instanceof LoadInstruction) { + addLiveVar(i, ((LoadInstruction) instr).getVarIndex()); + } + } + } + + private String getAndCheckLocalType(int i, int l) { + String[] lts = localTypes[i]; + String t = TYPE_unknown; + if (l < lts.length) { + t = lts[l]; + } + if (t.equals(TYPE_null) || t.equals(TYPE_unknown)) { + throw new IllegalArgumentException("Cannot split oversized method because local " + l + " is undefined at " + i); + } + return t; + } + + private void allocateLocals(int count) { + if (maxLocals < allocatedLocals + count * 2) { + maxLocals = allocatedLocals + count * 2; + } + } + + private HelperPatch makeHelperPatch(int start, int len, int retVar, int unreadStack, int untouchedStack) { + String retType = retVar >= 0 ? getAndCheckLocalType(start + len, retVar) : "V"; + + ArrayList callWrapper = new ArrayList(); + int curStackLen = stackTypes[start].length; + + StringBuffer sigBuf = new StringBuffer(); + sigBuf.append("("); + // spill needed stack variables to allocated locals; + allocateLocals(curStackLen - unreadStack); + for (int i = curStackLen - 1; i >= unreadStack; i--) { + if (i < untouchedStack) { + callWrapper.add(DupInstruction.make(0)); + } + callWrapper.add(StoreInstruction.make(stackTypes[start][i], allocatedLocals + 2 * (i - unreadStack))); + } + // push needed locals + BitSet liveVars = liveLocals[start]; + for (int i = 0; i < liveVars.length(); i++) { + if (liveVars.get(i)) { + String t = getAndCheckLocalType(start, i); + sigBuf.append(t); + callWrapper.add(LoadInstruction.make(t, i)); + if (Util.getWordSize(t) > 1) { + i++; + } + } else { + // dummy + sigBuf.append("I"); + callWrapper.add(ConstantInstruction.make(0)); + } + } + // push stack variables + for (int i = unreadStack; i < curStackLen; i++) { + callWrapper.add(LoadInstruction.make(stackTypes[start][i], allocatedLocals + 2 * (i - unreadStack))); + sigBuf.append(stackTypes[start][i]); + if (Util.getWordSize(stackTypes[start][i]) == 2) { + sigBuf.append("I"); + callWrapper.add(ConstantInstruction.make(0)); + } + } + sigBuf.append(")"); + sigBuf.append(retType); + String sig = sigBuf.toString(); + + String name = createHelperMethod(true, sig); + + callWrapper.add(InvokeInstruction.make(sig, classType, name, IInvokeInstruction.Dispatch.STATIC)); + + int savedMaxStack = maxStack; + maxStack += curStackLen - unreadStack; + + int prefixLength = 4 * (curStackLen - unreadStack); + byte[] initialStack = new byte[curStackLen - unreadStack]; + for (int i = 0; i < initialStack.length; i++) { + initialStack[i] = Util.getWordSize(stackTypes[start][unreadStack + i]); + } + if (!outputInstructions(start, start + len, prefixLength, false, initialStack)) { + throw new Error("Helper function is overlarge"); + } + byte[] newCode = new byte[code.length + (retVar >= 0 ? 5 : 1)]; + for (int i = 0; i < curStackLen - unreadStack; i++) { + int local = allocatedLocals + i * 2; + newCode[i * 4] = (byte) OP_wide; + newCode[i * 4 + 1] = (byte) LoadInstruction.make(stackTypes[start][i + unreadStack], 500).getOpcode(); + newCode[i * 4 + 2] = (byte) (local >> 8); + newCode[i * 4 + 3] = (byte) local; + } + System.arraycopy(code, prefixLength, newCode, prefixLength, code.length - prefixLength); + int suffixOffset = code.length; + if (retVar >= 0) { + newCode[suffixOffset] = (byte) OP_wide; + newCode[suffixOffset + 1] = (byte) LoadInstruction.make(retType, 500).getOpcode(); + newCode[suffixOffset + 2] = (byte) (retVar >> 8); + newCode[suffixOffset + 3] = (byte) retVar; + newCode[suffixOffset + 4] = (byte) ReturnInstruction.make(retType).getOpcode(); + callWrapper.add(StoreInstruction.make(retType, retVar)); + } else { + newCode[suffixOffset] = (byte) ReturnInstruction.make(TYPE_void).getOpcode(); + } + + if (callWrapper.size() > len) { + return null; + } + + int[] rawHandlers = buildRawHandlers(start, start + len); + int[] bytecodeMap = buildBytecodeMap(start, start + len); + + auxMethods.add(new Output(name, sig, newCode, rawHandlers, bytecodeMap, maxLocals, maxStack, true)); + + maxStack = savedMaxStack; + + Instruction[] patch = new Instruction[callWrapper.size()]; + callWrapper.toArray(patch); + + ExceptionHandler[] startHS = handlers[start]; + ArrayList newHS = new ArrayList(); + for (int i = 0; i < startHS.length; i++) { + int t = startHS[i].handler; + if (t < start || t >= start + len) { + newHS.add(startHS[i]); + } + } + ExceptionHandler[] patchHS = new ExceptionHandler[newHS.size()]; + newHS.toArray(patchHS); + + return new HelperPatch(start, len, patch, patchHS); + } + + private HelperPatch findBlock(int start, int len) { + while (len > 100) { + // make sure there is at most one entry + int lastInvalid = start - 1; + for (int i = start + 1; i < start + len; i++) { + int[] back = backEdges[i]; + boolean outsideBranch = false; + for (int j = 0; back != null && j < back.length; j++) { + if (back[j] < start || back[j] >= start + len) { + outsideBranch = true; + } + } + if (outsideBranch) { + HelperPatch p = findBlock(lastInvalid + 1, i - lastInvalid - 1); + if (p != null) { + return p; + } + lastInvalid = i; + } + } + if (lastInvalid >= start) { + return null; + } + + // make sure there is at most one exit (fall through at the end) + if (!instructions[start + len - 1].isFallThrough()) { + len--; + continue; + } + lastInvalid = start - 1; + for (int i = start; i < start + len; i++) { + int[] targets = instructions[i].getBranchTargets(); + boolean outsideBranch = false; + if (instructions[i] instanceof ReturnInstruction) { + outsideBranch = true; + } + for (int j = 0; j < targets.length; j++) { + if (targets[j] < start || targets[j] >= start + len) { + outsideBranch = true; + } + } + if (outsideBranch) { + HelperPatch p = findBlock(lastInvalid + 1, i - lastInvalid - 1); + if (p != null) { + return p; + } + lastInvalid = i; + } + } + if (lastInvalid >= start) { + return null; + } + + lastInvalid = start - 1; + for (int i = start; i < start + len; i++) { + boolean out = false; + ExceptionHandler[] hs = handlers[i]; + for (int j = 0; j < hs.length; j++) { + int h = hs[j].handler; + if (h < start || h >= start + len) { + out = true; + } + } + int[] targets = instructions[i].getBranchTargets(); + for (int j = 0; j < targets.length; j++) { + int t = targets[j]; + if (t < start || t >= start + len) { + out = true; + } + } + if (out) { + HelperPatch p = findBlock(lastInvalid + 1, i - lastInvalid - 1); + if (p != null) { + return p; + } + lastInvalid = i; + } + } + + if (lastInvalid >= start) { + return null; + } + + if (stackTypes[start] == null) { + while (stackTypes[start] == null && len > 0) { + start++; + len--; + } + continue; + } + + // See how many stack elements at entry are still there, unchanged, at + // exit + int untouchedStack = Integer.MAX_VALUE; + // See how many elements of that part of the stack are never even read + int unreadStack = Integer.MAX_VALUE; + for (int i = start; i < start + len; i++) { + if (stackTypes[i] == null) { + untouchedStack = 0; + unreadStack = 0; + break; + } + int lowWaterMark = stackTypes[i].length - instructions[i].getPoppedCount(); + unreadStack = Math.min(unreadStack, lowWaterMark); + if (instructions[i] instanceof DupInstruction) { + // dup instructions don't actually pop off/change the element they + // duplicate + lowWaterMark += instructions[i].getPoppedCount(); + } + untouchedStack = Math.min(untouchedStack, lowWaterMark); + } + + if (untouchedStack > unreadStack + 1 || (untouchedStack == unreadStack + 1 && untouchedStack < stackTypes[start].length)) { + // we can only handle 1 read-but-untouched element + start++; + len--; + continue; + } + + // make sure we know the type of all the stack values that must be passed + // in + boolean unknownType = false; + for (int i = unreadStack; i < untouchedStack; i++) { + String t = stackTypes[start][i]; + if (t == null || t.equals(TYPE_unknown) || t.equals(TYPE_null)) { + unknownType = true; + break; + } + } + if (unknownType) { + start++; + len--; + continue; + } + + // make sure outgoing stack size is no more than the untouched stack size. + if (stackTypes[start + len] == null || stackTypes[start + len].length > untouchedStack) { + // This is a little conservative. We might be able to stop sooner with a + // valid + // extractable method, because changing 'len' might mean we have more + // untouched stack elements. But we'll do this in a dumb way to avoid + // being caught in some N^2 loop looking for extractable code. + while (len > 0 && stackTypes[start + len] == null || stackTypes[start + len].length > untouchedStack) { + len--; + } + continue; + } + + // make sure at most one local is defined and live on exit + BitSet liveAtEnd = (BitSet) liveLocals[start + len]; + boolean multipleDefs = false; + int localDefed = -1; + int firstDef = -1; + int secondDef = -1; + for (int i = start; i < start + len; i++) { + Instruction instr = instructions[i]; + if (instr instanceof StoreInstruction) { + int l = ((StoreInstruction) instr).getVarIndex(); + if (liveAtEnd.get(l) && l != localDefed) { + if (localDefed < 0) { + localDefed = l; + firstDef = i; + } else { + multipleDefs = true; + secondDef = i; + break; + } + } + } + } + + if (multipleDefs) { + HelperPatch p = findBlock(start, secondDef - start); + if (p != null) { + return p; + } + len = (start + len) - (firstDef + 1); + start = firstDef + 1; + continue; + } + + // make sure that the same external handlers are used all the way through + ExceptionHandler[] startHS = handlers[start]; + int numOuts = 0; + for (int j = 0; j < startHS.length; j++) { + int t = startHS[j].handler; + if (t < start || t >= start + len) { + numOuts++; + } + } + boolean mismatchedHandlers = false; + int firstMismatch = -1; + for (int i = start + 1; i < start + len; i++) { + ExceptionHandler[] hs = handlers[i]; + int matchingOuts = 0; + for (int j = 0; j < hs.length; j++) { + int t = hs[j].handler; + if (t < start || t >= start + len) { + boolean match = false; + for (int k = 0; k < startHS.length; k++) { + if (startHS[k].equals(hs[j])) { + match = true; + break; + } + } + if (match) { + matchingOuts++; + } + } + } + if (matchingOuts != numOuts) { + firstMismatch = i; + mismatchedHandlers = true; + break; + } + } + if (mismatchedHandlers) { + HelperPatch p = findBlock(start, firstMismatch - start); + if (p != null) { + return p; + } + start = firstMismatch; + continue; + } + + // all conditions satisfied, extract the code + try { + HelperPatch p = makeHelperPatch(start, len, localDefed, unreadStack, untouchedStack); + if (p == null) { + // something went wrong. Probably the code to call the helper ended up + // being + // bigger than the original code we extracted! + return null; + } else { + return p; + } + } catch (IllegalArgumentException ex) { + return null; + } + } + + return null; + } + + private void makeHelpers() { + int offset = 0; + ArrayList patches = new ArrayList(); + + while (offset + 5000 < instructions.length) { + HelperPatch p = findBlock(offset, 5000); + if (p != null) { + patches.add(p); + offset = p.start + p.length; + } else { + offset += 500; + } + } + + for (Iterator i = patches.iterator(); i.hasNext();) { + HelperPatch p = i.next(); + + System.arraycopy(p.code, 0, instructions, p.start, p.code.length); + for (int j = 0; j < p.length; j++) { + int index = j + p.start; + if (j < p.code.length) { + instructions[index] = p.code[j]; + } else { + instructions[index] = PopInstruction.make(0); // nop + } + handlers[index] = p.handlers; + instructionsToBytecodes[index] = -1; + } + } + } + + private void makeTypes() { + Verifier v = new Verifier(isStatic, classType, signature, instructions, handlers); + if (hierarchy != null) { + v.setClassHierarchy(hierarchy); + } + try { + v.computeTypes(); + } catch (Verifier.FailureException ex) { + throw new IllegalArgumentException("Cannot split oversized method because verification failed: " + ex.getMessage()); + } + localTypes = v.getLocalTypes(); + stackTypes = v.getStackTypes(); + } + + /** + * Do the work of generating new bytecodes. + * + * In pathological cases this could throw an Error, when the code you passed + * in is too large to fit into a single JVM method and Compiler can't find a + * way to break it up into helper methods. You probably won't encounter this + * unless you try to make it happen :-). + */ + final public void compile() { + collectInstructionInfo(); + + computeStackWords(); + + if (!outputInstructions(0, instructions.length, 0, false, null)) { + allocatedLocals = maxLocals; + makeLiveLocals(); + makeTypes(); + auxMethods = new ArrayList(); + makeHelpers(); + + computeStackWords(); + if (!outputInstructions(0, instructions.length, 0, false, null)) { + throw new Error("Input code too large; consider breaking up your code"); + } + } + mainMethod = new Output(null, null, code, buildRawHandlers(0, instructions.length), buildBytecodeMap(0, instructions.length), + maxLocals, maxStack, isStatic); + + instructionsToOffsets = null; + branchTargets = null; + stackWords = null; + code = null; + } + + /** + * Get the output bytecodes and other information for the method. + */ + final public Output getOutput() { + return mainMethod; + } + + /** + * Get bytecodes and other information for any helper methods that are + * required to implement the main method. These helpers represent code that + * could not be fit into the main method because of JVM method size + * constraints. + */ + final public Output[] getAuxiliaryMethods() { + if (auxMethods == null) { + return null; + } else { + Output[] r = new Output[auxMethods.size()]; + auxMethods.toArray(r); + return r; + } + } + + /** + * This class represents a method generated by a Compiler. One input method to + * the Compiler can generate multiple Outputs (if the input method is too big + * to be represented by a single method in the JVM, say if it requires more + * than 64K bytecodes). + */ + public final static class Output { + private byte[] code; + private int[] rawHandlers; + private int[] newBytecodesToOldBytecodes; + private String name; + private String signature; + private boolean isStatic; + private int maxLocals; + private int maxStack; + + Output(String name, String signature, byte[] code, int[] rawHandlers, int[] newBytecodesToOldBytecodes, int maxLocals, + int maxStack, boolean isStatic) { + this.code = code; + this.name = name; + this.signature = signature; + this.rawHandlers = rawHandlers; + this.newBytecodesToOldBytecodes = newBytecodesToOldBytecodes; + this.isStatic = isStatic; + this.maxLocals = maxLocals; + this.maxStack = maxStack; + } + + /** + * @return the actual bytecodes + */ + public byte[] getCode() { + return code; + } + + /** + * @return the name of the method; either "null", if this code takes the + * place of the original method, or some string representing the + * name of a helper method + */ + public String getMethodName() { + return name; + } + + /** + * @return the method signature in JVM format + */ + public String getMethodSignature() { + return signature; + } + + /** + * @return the access flags that should be used for this method, or 0 if + * this is the code for the original method + */ + public int getAccessFlags() { + return name != null ? (ACC_PRIVATE | (isStatic ? ACC_STATIC : 0)) : 0; + } + + /** + * @return the raw exception handler table in JVM format + */ + public int[] getRawHandlers() { + return rawHandlers; + } + + /** + * @return whether the method is static + */ + public boolean isStatic() { + return isStatic; + } + + /** + * @return a map m such that the new bytecode instruction at offset i + * corresponds to the bytecode instruction at m[i] in the original + * method + */ + public int[] getNewBytecodesToOldBytecodes() { + return newBytecodesToOldBytecodes; + } + + /** + * @return the maximum stack size in words as required by the JVM + */ + public int getMaxStack() { + return maxStack; + } + + /** + * @return the maximum local variable size in words as required by the JVM + */ + public int getMaxLocals() { + return maxLocals; + } + } +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/ConditionalBranchInstruction.java b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/ConditionalBranchInstruction.java new file mode 100644 index 000000000..e3726594f --- /dev/null +++ b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/ConditionalBranchInstruction.java @@ -0,0 +1,123 @@ +/******************************************************************************* + * 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.shrikeBT; + +/** + * This class represents conditional branches. A conditional branch tests two + * integers or two object references for some relationship, and takes the branch + * if the relationship holds. + */ +public final class ConditionalBranchInstruction extends Instruction { + + public interface IOperator {}; + + public enum Operator implements IOperator { + EQ, NE, LT, GE, GT, LE; + + @Override + public String toString() { + return super.toString().toLowerCase(); + } + } + + private int label; + + protected ConditionalBranchInstruction(short opcode, int label) { + this.opcode = opcode; + this.label = label; + } + + public static ConditionalBranchInstruction make(String type, Operator operator, int label) { + int t = Util.getTypeIndex(type); + short opcode; + + switch (t) { + case TYPE_int_index: + opcode = (short) (OP_if_icmpeq + (operator.ordinal() - Operator.EQ.ordinal())); + break; + case TYPE_Object_index: + if (operator != Operator.EQ && operator != Operator.NE) { + throw new IllegalArgumentException("Cannot test for condition " + operator + " on a reference"); + } + opcode = (short) (OP_if_acmpeq + (operator.ordinal() - Operator.EQ.ordinal())); + break; + default: + throw new IllegalArgumentException("Cannot conditionally branch on a value of type " + type); + } + + return make(opcode, label); + } + + //Relax from private to public by Xiangyu, to create ifeq + public static ConditionalBranchInstruction make(short opcode, int label) { + return new ConditionalBranchInstruction(opcode, label); + } + + public boolean equals(Object o) { + if (o instanceof ConditionalBranchInstruction) { + ConditionalBranchInstruction i = (ConditionalBranchInstruction) o; + return i.opcode == opcode && i.label == label; + } else { + return false; + } + } + + public String toString() { + return "ConditionalBranch(" + getType() + "," + getOperator() + "," + label + ")"; + } + + public int[] getBranchTargets() { + int[] r = { label }; + return r; + } + + public int getTarget() { + return label; + } + + public Instruction redirectTargets(int[] targetMap) { + return make(opcode, targetMap[label]); + } + + public Operator getOperator() { + if (opcode < OP_if_acmpeq) { + return Operator.values()[opcode - OP_if_icmpeq]; + } else { + return Operator.values()[opcode - OP_if_acmpeq]; + } + } + + public String getType() { + return opcode < OP_if_acmpeq ? TYPE_int : TYPE_Object; + } + + public int hashCode() { + return 30190 * opcode + 384101 * label; + } + + public int getPoppedCount() { + //Xiangyu, to support if_eq (if_ne)... + if (opcode >= Constants.OP_ifeq && opcode <= Constants.OP_ifle) + return 1; + return 2; + } + + public void visit(Visitor v) { + v.visitConditionalBranch(this); + } + + /* (non-Javadoc) + * @see com.ibm.domo.cfg.IInstruction#isPEI() + */ + public boolean isPEI() { + return false; + } +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/ConstantInstruction.java b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/ConstantInstruction.java new file mode 100644 index 000000000..5d650fbdd --- /dev/null +++ b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/ConstantInstruction.java @@ -0,0 +1,553 @@ +/******************************************************************************* + * 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.shrikeBT; + +/** + * A ConstantInstruction pushes some constant value onto the stack. + */ +public abstract class ConstantInstruction extends Instruction { + ConstantInstruction() { + } + + ConstantPoolReader getLazyConstantPool() { + return null; + } + + int getCPIndex() { + return 0; + } + + final static class ConstNull extends ConstantInstruction { + protected ConstNull() { + opcode = OP_aconst_null; + } + + private final static ConstNull preallocated = new ConstNull(); + + static ConstNull makeInternal() { + return preallocated; + } + + public Object getValue() { + return null; + } + + public String getType() { + return TYPE_null; + } + } + + static class ConstInt extends ConstantInstruction { + protected int value; + + private final static ConstInt[] preallocated = preallocate(); + + protected ConstInt(short opcode, int value) { + this.opcode = opcode; + this.value = value; + } + + private static ConstInt[] preallocate() { + ConstInt[] r = new ConstInt[256]; + for (int i = 0; i < r.length; i++) { + r[i] = new ConstInt(OP_bipush, i - 128); + } + for (int i = -1; i <= 5; i++) { + r[i + 128] = new ConstInt((short) (i - (-1) + OP_iconst_m1), i); + } + return r; + } + + static ConstInt makeInternal(int i) { + if (((byte) i) == i) { + return preallocated[i + 128]; + } else if (((short) i) == i) { + return new ConstInt(OP_sipush, i); + } else { + return new ConstInt(OP_ldc_w, i); + } + } + + final public Object getValue() { + return new Integer(getIntValue()); + } + + final public String getType() { + return TYPE_int; + } + + public int getIntValue() { + return value; + } + } + + final static class LazyInt extends ConstInt { + private ConstantPoolReader cp; + private int index; + private boolean isSet; + + protected LazyInt(short opcode, ConstantPoolReader cp, int index) { + super(opcode, 0); + this.cp = cp; + this.index = index; + this.isSet = false; + } + + public int getIntValue() { + if (!isSet) { + value = cp.getConstantPoolInteger(index); + isSet = true; + } + return value; + } + + public ConstantPoolReader getLazyConstantPool() { + return cp; + } + + public int getCPIndex() { + return index; + } + } + + static class ConstLong extends ConstantInstruction { + protected long value; + + private final static ConstLong[] preallocated = preallocate(); + + protected ConstLong(short opcode, long value) { + this.opcode = opcode; + this.value = value; + } + + private static ConstLong[] preallocate() { + ConstLong[] r = { new ConstLong(OP_lconst_0, 0), new ConstLong(OP_lconst_1, 1) }; + return r; + } + + static ConstLong makeInternal(long v) { + if (v == 0 || v == 1) { + return preallocated[(int) v]; + } else { + return new ConstLong(OP_ldc2_w, v); + } + } + + final public Object getValue() { + return new Long(getLongValue()); + } + + final public String getType() { + return TYPE_long; + } + + public long getLongValue() { + return value; + } + } + + final static class LazyLong extends ConstLong { + private ConstantPoolReader cp; + private int index; + private boolean isSet; + + protected LazyLong(short opcode, ConstantPoolReader cp, int index) { + super(opcode, 0); + this.cp = cp; + this.index = index; + this.isSet = false; + } + + public long getLongValue() { + if (!isSet) { + value = cp.getConstantPoolLong(index); + isSet = true; + } + return value; + } + + public ConstantPoolReader getLazyConstantPool() { + return cp; + } + + public int getCPIndex() { + return index; + } + } + + static class ConstFloat extends ConstantInstruction { + protected float value; + + private final static ConstFloat[] preallocated = preallocate(); + + protected ConstFloat(short opcode, float value) { + this.opcode = opcode; + this.value = value; + } + + private static ConstFloat[] preallocate() { + ConstFloat[] r = { new ConstFloat(OP_fconst_0, 0), new ConstFloat(OP_fconst_1, 1), new ConstFloat(OP_fconst_2, 2) }; + return r; + } + + static ConstFloat makeInternal(float v) { + if (v == 0.0 || v == 1.0 || v == 2.0) { + return preallocated[(int) v]; + } else { + return new ConstFloat(OP_ldc_w, v); + } + } + + final public Object getValue() { + return new Float(getFloatValue()); + } + + final public String getType() { + return TYPE_float; + } + + public float getFloatValue() { + return value; + } + } + + final static class LazyFloat extends ConstFloat { + private ConstantPoolReader cp; + private int index; + private boolean isSet; + + protected LazyFloat(short opcode, ConstantPoolReader cp, int index) { + super(opcode, 0.0f); + this.cp = cp; + this.index = index; + this.isSet = false; + } + + public float getFloatValue() { + if (!isSet) { + value = cp.getConstantPoolFloat(index); + isSet = true; + } + return value; + } + + public ConstantPoolReader getLazyConstantPool() { + return cp; + } + + public int getCPIndex() { + return index; + } + } + + static class ConstDouble extends ConstantInstruction { + protected double value; + + private final static ConstDouble[] preallocated = preallocate(); + + protected ConstDouble(short opcode, double value) { + this.opcode = opcode; + this.value = value; + } + + private static ConstDouble[] preallocate() { + ConstDouble[] r = { new ConstDouble(OP_dconst_0, 0), new ConstDouble(OP_dconst_1, 1) }; + return r; + } + + static ConstDouble makeInternal(double v) { + if (v == 0.0 || v == 1.0) { + return preallocated[(int) v]; + } else { + return new ConstDouble(OP_ldc2_w, v); + } + } + + final public Object getValue() { + return new Double(getDoubleValue()); + } + + final public String getType() { + return TYPE_double; + } + + public double getDoubleValue() { + return value; + } + } + + final static class LazyDouble extends ConstDouble { + private ConstantPoolReader cp; + private int index; + private boolean isSet; + + protected LazyDouble(short opcode, ConstantPoolReader cp, int index) { + super(opcode, 0.0); + this.cp = cp; + this.index = index; + this.isSet = false; + } + + public double getDoubleValue() { + if (!isSet) { + value = cp.getConstantPoolDouble(index); + isSet = true; + } + return value; + } + + public ConstantPoolReader getLazyConstantPool() { + return cp; + } + + public int getCPIndex() { + return index; + } + } + + static class ConstString extends ConstantInstruction { + protected String value; + + protected ConstString(short opcode, String value) { + this.opcode = opcode; + this.value = value; + } + + static ConstString makeInternal(String v) { + return new ConstString(OP_ldc_w, v); + } + + public Object getValue() { + return value; + } + + final public String getType() { + return TYPE_String; + } + } + + final static class LazyString extends ConstString { + private ConstantPoolReader cp; + private int index; + + protected LazyString(short opcode, ConstantPoolReader cp, int index) { + super(opcode, null); + this.cp = cp; + this.index = index; + } + + public Object getValue() { + if (value == null) { + value = cp.getConstantPoolString(index); + } + return value; + } + + public ConstantPoolReader getLazyConstantPool() { + return cp; + } + + public int getCPIndex() { + return index; + } + } + + static class ConstClass extends ConstantInstruction { + protected String typeName; + + protected ConstClass(short opcode, String typeName) { + this.opcode = opcode; + this.typeName = typeName; + } + + static ConstClass makeInternal(String v) { + return new ConstClass(OP_ldc_w, v); + } + + public Object getValue() { + return typeName; + } + + final public String getType() { + return TYPE_Class; + } + } + + final static class LazyClass extends ConstClass { + private ConstantPoolReader cp; + private int index; + + protected LazyClass(short opcode, ConstantPoolReader cp, int index) { + super(opcode, null); + this.cp = cp; + this.index = index; + } + + public Object getValue() { + if (typeName == null) { + typeName = cp.getConstantPoolClassType(index); + } + return typeName; + } + + public ConstantPoolReader getLazyConstantPool() { + return cp; + } + + public int getCPIndex() { + return index; + } + } + + /** + * @return the constant value pushed: an Integer, a Long, a Float, a Double, a + * String, or null + */ + public abstract Object getValue(); + + /** + * @return the type of the value pushed + */ + public abstract String getType(); + + public static ConstantInstruction make(String type, Object constant) { + if (constant == null) { + return ConstNull.makeInternal(); + } else if (type.equals(TYPE_String)) { + return makeString((String) constant); + } else if (type.equals(TYPE_Class)) { + return makeClass((String) constant); + } else { + switch (Util.getTypeIndex(type)) { + case TYPE_int_index: + return make(((Number) constant).intValue()); + case TYPE_long_index: + return make(((Number) constant).longValue()); + case TYPE_float_index: + return make(((Number) constant).floatValue()); + case TYPE_double_index: + return make(((Number) constant).doubleValue()); + default: + throw new IllegalArgumentException("Invalid type for constant: " + type); + } + } + } + + public static ConstantInstruction make(int i) { + return ConstInt.makeInternal(i); + } + + public static ConstantInstruction make(long l) { + return ConstLong.makeInternal(l); + } + + public static ConstantInstruction make(float f) { + return ConstFloat.makeInternal(f); + } + + public static ConstantInstruction make(double d) { + return ConstDouble.makeInternal(d); + } + + public static ConstantInstruction makeString(String s) { + return s == null ? (ConstantInstruction) ConstNull.makeInternal() : (ConstantInstruction) ConstString.makeInternal(s); + } + + public static ConstantInstruction makeClass(String s) { + return (ConstantInstruction) ConstClass.makeInternal(s); + } + + static ConstantInstruction make(ConstantPoolReader cp, int index) { + switch (cp.getConstantPoolItemType(index)) { + case CONSTANT_Integer: + return new LazyInt(OP_ldc_w, cp, index); + case CONSTANT_Long: + return new LazyLong(OP_ldc2_w, cp, index); + case CONSTANT_Float: + return new LazyFloat(OP_ldc_w, cp, index); + case CONSTANT_Double: + return new LazyDouble(OP_ldc2_w, cp, index); + case CONSTANT_String: + return new LazyString(OP_ldc_w, cp, index); + case CONSTANT_Class: + return new LazyClass(OP_ldc_w, cp, index); + default: + return null; + } + } + + final public boolean equals(Object o) { + if (o instanceof ConstantInstruction) { + ConstantInstruction i = (ConstantInstruction) o; + return i.getType().equals(getType()) && i.getValue().equals(getValue()); + } else { + return false; + } + } + + final public String getPushedType(String[] types) { + return getType(); + } + + final public byte getPushedWordSize() { + return Util.getWordSize(getType()); + } + + final public int hashCode() { + return getType().hashCode() + 14411 * getValue().hashCode(); + } + + final public void visit(Visitor v) { + v.visitConstant(this); + } + + private static String quote(Object o) { + if (o instanceof String) { + String s = (String) o; + StringBuffer buf = new StringBuffer("\""); + int len = s.length(); + for (int i = 0; i < len; i++) { + char ch = s.charAt(i); + switch (ch) { + case '"': + buf.append('\\'); + buf.append(ch); + break; + case '\n': + buf.append("\\\n"); + break; + case '\t': + buf.append("\\\t"); + break; + default: + buf.append(ch); + } + } + buf.append("\""); + return buf.toString(); + } else if (o == null) { + return "null"; + } else { + return o.toString(); + } + } + + final public String toString() { + return "Constant(" + getType() + "," + quote(getValue()) + ")"; + } + + /* (non-Javadoc) + * @see com.ibm.domo.cfg.IInstruction#isPEI() + */ + public boolean isPEI() { + return false; + } +} diff --git a/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/ConstantPoolReader.java b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/ConstantPoolReader.java new file mode 100644 index 000000000..b2facdc1f --- /dev/null +++ b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/ConstantPoolReader.java @@ -0,0 +1,113 @@ +/******************************************************************************* + * 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.shrikeBT; + +/** + * This class provides read-only access to a constant pool. It gets subclassed + * for each class reader/editor toolkit you want to work with. + */ +public abstract class ConstantPoolReader { + /** + * Retrieve the JVM constant pool item type (a Constants.CONSTANT_xxx value). + * This method should be overriden by a toolkit-specific subclass. + * + * @param index + * the constant pool item to examine + */ + public abstract int getConstantPoolItemType(int index); + + /** + * Retrieve the value of a CONSTANT_Integer constant pool item. This method + * should be overriden by a toolkit-specific subclass. + * + * @param index + * the constant pool item to examine + */ + public abstract int getConstantPoolInteger(int index); + + /** + * Retrieve the value of a CONSTANT_Float constant pool item. This method + * should be overriden by a toolkit-specific subclass. + * + * @param index + * the constant pool item to examine + */ + public abstract float getConstantPoolFloat(int index); + + /** + * Retrieve the value of a CONSTANT_Long constant pool item. This method + * should be overriden by a toolkit-specific subclass. + * + * @param index + * the constant pool item to examine + */ + public abstract long getConstantPoolLong(int index); + + /** + * Retrieve the value of a CONSTANT_Double constant pool item. This method + * should be overriden by a toolkit-specific subclass. + * + * @param index + * the constant pool item to examine + */ + public abstract double getConstantPoolDouble(int index); + + /** + * Retrieve the value of a CONSTANT_String constant pool item. This method + * should be overriden by a toolkit-specific subclass. + * + * @param index + * the constant pool item to examine + */ + public abstract String getConstantPoolString(int index); + + /** + * Retrieve the value of a CONSTANT_Class constant pool item in JVM internal + * class format (e.g., java/lang/Object). This method should be overriden by a + * toolkit-specific subclass. + * + * @param index + * the constant pool item to examine + */ + public abstract String getConstantPoolClassType(int index); + + /** + * Retrieve the class part of a CONSTANT_FieldRef, CONSTANT_MethodRef, or + * CONSTANT_InterfaceMethodRef constant pool item, in JVM internal class + * format (e.g., java/lang/Object). This method should be overriden by a + * toolkit-specific subclass. + * + * @param index + * the constant pool item to examine + */ + public abstract String getConstantPoolMemberClassType(int index); + + /** + * Retrieve the name part of a CONSTANT_FieldRef, CONSTANT_MethodRef, or + * CONSTANT_InterfaceMethodRef constant pool item, This method should be + * overriden by a toolkit-specific subclass. + * + * @param index + * the constant pool item to examine + */ + public abstract String getConstantPoolMemberName(int index); + + /** + * Retrieve the type part of a CONSTANT_FieldRef, CONSTANT_MethodRef, or + * CONSTANT_InterfaceMethodRef constant pool item, in JVM internal type format + * (e.g., Ljava/lang/Object;). This method should be overriden by a + * toolkit-specific subclass. + * + * @param index + * the constant pool item to examine + */ + public abstract String getConstantPoolMemberType(int index); +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/Constants.java b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/Constants.java new file mode 100644 index 000000000..a727e7092 --- /dev/null +++ b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/Constants.java @@ -0,0 +1,327 @@ +/******************************************************************************* + * 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.shrikeBT; + +/** + * This interface defines a bunch of constants from the JVM spec. It also + * defines some constants we need for other purposes. + * + * Here are the JVM constants: + *
                                + *
                              • The OP_ constants define the JVM instruction opcodes. + *
                              • The ACC_ constants define the accessibility flags for classes, fields + * and methods. + *
                              • The CONSTANT_ constants define the constant pool item types. + *
                              • The T_ constants define the types of arrays that can be created by + * OP_newarray. + *
                              • The TYPE_ constants define the string representations of various JVM + * types. Two special non-JVM types are defined, TYPE_null and TYPE_unknown, as + * noted below. + *
                              + * + * Non-JVM constants: + *
                                + *
                              • The OPR_ constants define the set of operators present in JVM + * instructions. + *
                              • The operatorNames array gives the string names of those operators. + *
                              • The TYPE_..._index constants define numeric representations of the JVM + * base types. + *
                              • The indexedTypes array maps those numeric representations to their + * official string representations. + *
                              • The indexedTypes_T array maps those numeric representations to the + * corresponding T_ constant. + *
                              + */ +public interface Constants { + + public static final short OP_nop = 0; + public static final short OP_aconst_null = 1; + public static final short OP_iconst_m1 = 2; + public static final short OP_iconst_0 = 3; + public static final short OP_iconst_1 = 4; + public static final short OP_iconst_2 = 5; + public static final short OP_iconst_3 = 6; + public static final short OP_iconst_4 = 7; + public static final short OP_iconst_5 = 8; + public static final short OP_lconst_0 = 9; + public static final short OP_lconst_1 = 10; + public static final short OP_fconst_0 = 11; + public static final short OP_fconst_1 = 12; + public static final short OP_fconst_2 = 13; + public static final short OP_dconst_0 = 14; + public static final short OP_dconst_1 = 15; + public static final short OP_bipush = 16; + public static final short OP_sipush = 17; + public static final short OP_ldc = 18; + public static final short OP_ldc_w = 19; + public static final short OP_ldc2_w = 20; + public static final short OP_iload = 21; + public static final short OP_lload = 22; + public static final short OP_fload = 23; + public static final short OP_dload = 24; + public static final short OP_aload = 25; + public static final short OP_iload_0 = 26; + public static final short OP_iload_1 = 27; + public static final short OP_iload_2 = 28; + public static final short OP_iload_3 = 29; + public static final short OP_lload_0 = 30; + public static final short OP_lload_1 = 31; + public static final short OP_lload_2 = 32; + public static final short OP_lload_3 = 33; + public static final short OP_fload_0 = 34; + public static final short OP_fload_1 = 35; + public static final short OP_fload_2 = 36; + public static final short OP_fload_3 = 37; + public static final short OP_dload_0 = 38; + public static final short OP_dload_1 = 39; + public static final short OP_dload_2 = 40; + public static final short OP_dload_3 = 41; + public static final short OP_aload_0 = 42; + public static final short OP_aload_1 = 43; + public static final short OP_aload_2 = 44; + public static final short OP_aload_3 = 45; + public static final short OP_iaload = 46; + public static final short OP_laload = 47; + public static final short OP_faload = 48; + public static final short OP_daload = 49; + public static final short OP_aaload = 50; + public static final short OP_baload = 51; + public static final short OP_caload = 52; + public static final short OP_saload = 53; + public static final short OP_istore = 54; + public static final short OP_lstore = 55; + public static final short OP_fstore = 56; + public static final short OP_dstore = 57; + public static final short OP_astore = 58; + public static final short OP_istore_0 = 59; + public static final short OP_istore_1 = 60; + public static final short OP_istore_2 = 61; + public static final short OP_istore_3 = 62; + public static final short OP_lstore_0 = 63; + public static final short OP_lstore_1 = 64; + public static final short OP_lstore_2 = 65; + public static final short OP_lstore_3 = 66; + public static final short OP_fstore_0 = 67; + public static final short OP_fstore_1 = 68; + public static final short OP_fstore_2 = 69; + public static final short OP_fstore_3 = 70; + public static final short OP_dstore_0 = 71; + public static final short OP_dstore_1 = 72; + public static final short OP_dstore_2 = 73; + public static final short OP_dstore_3 = 74; + public static final short OP_astore_0 = 75; + public static final short OP_astore_1 = 76; + public static final short OP_astore_2 = 77; + public static final short OP_astore_3 = 78; + public static final short OP_iastore = 79; + public static final short OP_lastore = 80; + public static final short OP_fastore = 81; + public static final short OP_dastore = 82; + public static final short OP_aastore = 83; + public static final short OP_bastore = 84; + public static final short OP_castore = 85; + public static final short OP_sastore = 86; + public static final short OP_pop = 87; + public static final short OP_pop2 = 88; + public static final short OP_dup = 89; + public static final short OP_dup_x1 = 90; + public static final short OP_dup_x2 = 91; + public static final short OP_dup2 = 92; + public static final short OP_dup2_x1 = 93; + public static final short OP_dup2_x2 = 94; + public static final short OP_swap = 95; + public static final short OP_iadd = 96; + public static final short OP_ladd = 97; + public static final short OP_fadd = 98; + public static final short OP_dadd = 99; + public static final short OP_isub = 100; + public static final short OP_lsub = 101; + public static final short OP_fsub = 102; + public static final short OP_dsub = 103; + public static final short OP_imul = 104; + public static final short OP_lmul = 105; + public static final short OP_fmul = 106; + public static final short OP_dmul = 107; + public static final short OP_idiv = 108; + public static final short OP_ldiv = 109; + public static final short OP_fdiv = 110; + public static final short OP_ddiv = 111; + public static final short OP_irem = 112; + public static final short OP_lrem = 113; + public static final short OP_frem = 114; + public static final short OP_drem = 115; + public static final short OP_ineg = 116; + public static final short OP_lneg = 117; + public static final short OP_fneg = 118; + public static final short OP_dneg = 119; + public static final short OP_ishl = 120; + public static final short OP_lshl = 121; + public static final short OP_ishr = 122; + public static final short OP_lshr = 123; + public static final short OP_iushr = 124; + public static final short OP_lushr = 125; + public static final short OP_iand = 126; + public static final short OP_land = 127; + public static final short OP_ior = 128; + public static final short OP_lor = 129; + public static final short OP_ixor = 130; + public static final short OP_lxor = 131; + public static final short OP_iinc = 132; + public static final short OP_i2l = 133; + public static final short OP_i2f = 134; + public static final short OP_i2d = 135; + public static final short OP_l2i = 136; + public static final short OP_l2f = 137; + public static final short OP_l2d = 138; + public static final short OP_f2i = 139; + public static final short OP_f2l = 140; + public static final short OP_f2d = 141; + public static final short OP_d2i = 142; + public static final short OP_d2l = 143; + public static final short OP_d2f = 144; + public static final short OP_i2b = 145; + public static final short OP_i2c = 146; + public static final short OP_i2s = 147; + public static final short OP_lcmp = 148; + public static final short OP_fcmpl = 149; + public static final short OP_fcmpg = 150; + public static final short OP_dcmpl = 151; + public static final short OP_dcmpg = 152; + public static final short OP_ifeq = 153; + public static final short OP_ifne = 154; + public static final short OP_iflt = 155; + public static final short OP_ifge = 156; + public static final short OP_ifgt = 157; + public static final short OP_ifle = 158; + public static final short OP_if_icmpeq = 159; + public static final short OP_if_icmpne = 160; + public static final short OP_if_icmplt = 161; + public static final short OP_if_icmpge = 162; + public static final short OP_if_icmpgt = 163; + public static final short OP_if_icmple = 164; + public static final short OP_if_acmpeq = 165; + public static final short OP_if_acmpne = 166; + public static final short OP_goto = 167; + public static final short OP_jsr = 168; + public static final short OP_ret = 169; + public static final short OP_tableswitch = 170; + public static final short OP_lookupswitch = 171; + public static final short OP_ireturn = 172; + public static final short OP_lreturn = 173; + public static final short OP_freturn = 174; + public static final short OP_dreturn = 175; + public static final short OP_areturn = 176; + public static final short OP_return = 177; + public static final short OP_getstatic = 178; + public static final short OP_putstatic = 179; + public static final short OP_getfield = 180; + public static final short OP_putfield = 181; + public static final short OP_invokevirtual = 182; + public static final short OP_invokespecial = 183; + public static final short OP_invokestatic = 184; + public static final short OP_invokeinterface = 185; + public static final short OP_xxxunusedxxx = 186; + public static final short OP_new = 187; + public static final short OP_newarray = 188; + public static final short OP_anewarray = 189; + public static final short OP_arraylength = 190; + public static final short OP_athrow = 191; + public static final short OP_checkcast = 192; + public static final short OP_instanceof = 193; + public static final short OP_monitorenter = 194; + public static final short OP_monitorexit = 195; + public static final short OP_wide = 196; + public static final short OP_multianewarray = 197; + public static final short OP_ifnull = 198; + public static final short OP_ifnonnull = 199; + public static final short OP_goto_w = 200; + public static final short OP_jsr_w = 201; + + public static final short ACC_PUBLIC = 0x1; + public static final short ACC_PRIVATE = 0x2; + public static final short ACC_PROTECTED = 0x4; + public static final short ACC_STATIC = 0x8; + public static final short ACC_FINAL = 0x10; + public static final short ACC_SYNCHRONIZED = 0x20; + public static final short ACC_SUPER = 0x20; + public static final short ACC_VOLATILE = 0x40; + public static final short ACC_TRANSIENT = 0x80; + public static final short ACC_NATIVE = 0x100; + public static final short ACC_INTERFACE = 0x200; + public static final short ACC_ABSTRACT = 0x400; + public static final short ACC_STRICT = 0x800; + + public static final byte CONSTANT_Utf8 = 1; + public static final byte CONSTANT_Integer = 3; + public static final byte CONSTANT_Float = 4; + public static final byte CONSTANT_Long = 5; + public static final byte CONSTANT_Double = 6; + public static final byte CONSTANT_Class = 7; + public static final byte CONSTANT_String = 8; + public static final byte CONSTANT_FieldRef = 9; + public static final byte CONSTANT_MethodRef = 10; + public static final byte CONSTANT_InterfaceMethodRef = 11; + public static final byte CONSTANT_NameAndType = 12; + + public static final byte T_BOOLEAN = 4; + public static final byte T_CHAR = 5; + public static final byte T_FLOAT = 6; + public static final byte T_DOUBLE = 7; + public static final byte T_BYTE = 8; + public static final byte T_SHORT = 9; + public static final byte T_INT = 10; + public static final byte T_LONG = 11; + + public static final String TYPE_boolean = "Z"; + public static final String TYPE_byte = "B"; + public static final String TYPE_int = "I"; + public static final String TYPE_short = "S"; + public static final String TYPE_long = "J"; + public static final String TYPE_float = "F"; + public static final String TYPE_double = "D"; + public static final String TYPE_char = "C"; + public static final String TYPE_void = "V"; + public static final String TYPE_String = "Ljava/lang/String;"; + public static final String TYPE_Object = "Ljava/lang/Object;"; + public static final String TYPE_Throwable = "Ljava/lang/Throwable;"; + public static final String TYPE_Class = "Ljava/lang/Class;"; + public static final String TYPE_Exception = "Ljava/lang/Exception;"; + public static final String TYPE_RuntimeException = "Ljava/lang/RuntimeException;"; + public static final String TYPE_Error = "Ljava/lang/Error;"; + + /** + * This represents the type of "null", which can be any object. It is not + * defined by the JVM spec. + */ + public static final String TYPE_null = "L;"; + /** This represents a type which is unknown. It is not defined by the JVM spec. */ + public static final String TYPE_unknown = "L?;"; + + public static final byte TYPE_int_index = 0; + public static final byte TYPE_long_index = 1; + public static final byte TYPE_float_index = 2; + public static final byte TYPE_double_index = 3; + public static final byte TYPE_Object_index = 4; + public static final byte TYPE_byte_index = 5; + public static final byte TYPE_char_index = 6; + public static final byte TYPE_short_index = 7; + public static final byte TYPE_boolean_index = 8; + + public static final String[] indexedTypes = { TYPE_int, TYPE_long, TYPE_float, TYPE_double, TYPE_Object, TYPE_byte, TYPE_char, + TYPE_short, TYPE_boolean }; + + public static final byte[] indexedTypes_T = { T_INT, T_LONG, T_FLOAT, T_DOUBLE, 0, T_BYTE, T_CHAR, T_SHORT, T_BOOLEAN }; + + // these constants are used by analyses to report results + public static final int NO = 1; + public static final int YES = 2; + public static final int MAYBE = 3; +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/ConversionInstruction.java b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/ConversionInstruction.java new file mode 100644 index 000000000..0c57100cb --- /dev/null +++ b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/ConversionInstruction.java @@ -0,0 +1,117 @@ +/******************************************************************************* + * 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.shrikeBT; + +/** + * This class represents instructions that convert from one primitive type to + * another. + */ +public final class ConversionInstruction extends Instruction { + private String fromType; + private String toType; + + protected ConversionInstruction(short opcode) { + this.opcode = opcode; + + if (opcode < OP_i2b) { + int k = opcode - OP_i2l; + toType = indexedTypes[skip(k % 3, k / 3)]; + } else { + toType = indexedTypes[(opcode - OP_i2b) + TYPE_byte_index]; + } + + if (opcode < OP_i2b) { + fromType = indexedTypes[(opcode - OP_i2l) / 3]; + } else { + fromType = TYPE_int; + } + } + + private final static ConversionInstruction[] preallocated = preallocate(); + + private static ConversionInstruction[] preallocate() { + ConversionInstruction[] r = new ConversionInstruction[OP_i2s - OP_i2l + 1]; + for (short i = OP_i2l; i <= OP_i2s; i++) { + r[i - OP_i2l] = new ConversionInstruction(i); + } + return r; + } + + public static ConversionInstruction make(String fromType, String toType) { + int from = Util.getTypeIndex(fromType); + int to = Util.getTypeIndex(toType); + if (from < 0 || from > TYPE_double_index) { + throw new IllegalArgumentException("Cannot convert from type " + fromType); + } + if (from == TYPE_int_index && (to >= TYPE_byte_index && to <= TYPE_short_index)) { + return preallocated[(OP_i2b - OP_i2l) + (to - TYPE_byte_index)]; + } else { + if (to < 0 || to > TYPE_double_index) { + throw new IllegalArgumentException("Cannot convert from type " + fromType + " to type " + toType); + } + if (to == from) { + throw new IllegalArgumentException("Cannot convert from type " + fromType + " to same type"); + } + return preallocated[from * 3 + (to > from ? to - 1 : to)]; + } + } + + public int getPoppedCount() { + return 1; + } + + public String getFromType() { + return fromType; + } + + private static int skip(int a, int b) { + return a < b ? a : a + 1; + } + + public String getToType() { + return toType; + } + + public String getPushedType(String[] types) { + return getToType(); + } + + public byte getPushedWordSize() { + return Util.getWordSize(getToType()); + } + + public boolean equals(Object o) { + if (o instanceof ConversionInstruction) { + ConversionInstruction i = (ConversionInstruction) o; + return i.opcode == opcode; + } else { + return false; + } + } + + public int hashCode() { + return opcode * 143111; + } + + public String toString() { + return "Conversion(" + getFromType() + "," + getToType() + ")"; + } + + public void visit(Visitor v) { + v.visitConversion(this); + } + /* (non-Javadoc) + * @see com.ibm.domo.cfg.IInstruction#isPEI() + */ + public boolean isPEI() { + return false; + } +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/Decoder.java b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/Decoder.java new file mode 100644 index 000000000..0d24b9c9d --- /dev/null +++ b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/Decoder.java @@ -0,0 +1,1085 @@ +/******************************************************************************* + * 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.shrikeBT; + +import java.util.ArrayList; + +import com.ibm.wala.shrikeBT.BinaryOpInstruction.Operator; + +/** + * A Decoder translates a method's Java bytecode into shrikeBT code, i.e. an + * array of Instruction objects and an array of lists of ExceptionHandlers. + * + * This class implements basic decoding functionality. A toolkit for reading + * class files must specialize this class with particular constant pool reader + * implementation. + * + * Normal usage of this class looks like this: + * + *
                              + * 
                              + *    Decoder d = new MyToolkitDecoder(...);
                              + *    try {
                              + *      d.decode();
                              + *    } catch (Decoder.InvalidBytecodeException ex) {
                              + *      ...
                              + *    }
                              + *    Instruction[] myInstructions = d.getInstructions();
                              + *    ExceptionHandler[][] exnHandlers = d.getHandlers();
                              + *  
                              + * 
                              + */ +public abstract class Decoder implements Constants { + private static final int UNSEEN = -1; + private static final int INSIDE_INSTRUCTION = -2; + + private static int skip(int a, int b) { + return a < b ? a : a + 1; + } + + private final static ExceptionHandler[] noHandlers = new ExceptionHandler[0]; + + /** This holds predecoded instructions for the single-byte instructions. */ + private final static Instruction[] simpleInstructions = makeSimpleInstructions(); + + private static Instruction[] makeSimpleInstructions() { + Instruction[] table = new Instruction[256]; + + table[OP_aconst_null] = ConstantInstruction.make(TYPE_null, null); + for (int i = OP_iconst_m1; i <= OP_iconst_5; i++) { + table[i] = ConstantInstruction.make(TYPE_int, new Integer(i - OP_iconst_m1 - 1)); + } + for (int i = OP_lconst_0; i <= OP_lconst_1; i++) { + table[i] = ConstantInstruction.make(TYPE_long, new Long(i - OP_lconst_0)); + } + for (int i = OP_fconst_0; i <= OP_fconst_2; i++) { + table[i] = ConstantInstruction.make(TYPE_float, new Float(i - OP_fconst_0)); + } + for (int i = OP_dconst_0; i <= OP_dconst_1; i++) { + table[i] = ConstantInstruction.make(TYPE_double, new Double(i - OP_dconst_0)); + } + + for (int i = OP_iload_0; i <= OP_aload_3; i++) { + table[i] = LoadInstruction.make(indexedTypes[(i - OP_iload_0) / 4], (i - OP_iload_0) % 4); + } + for (int i = OP_iaload; i <= OP_saload; i++) { + table[i] = ArrayLoadInstruction.make(indexedTypes[i - OP_iaload]); + } + for (int i = OP_istore_0; i <= OP_astore_3; i++) { + table[i] = StoreInstruction.make(indexedTypes[(i - OP_istore_0) / 4], (i - OP_istore_0) % 4); + } + for (int i = OP_iastore; i <= OP_sastore; i++) { + table[i] = ArrayStoreInstruction.make(indexedTypes[i - OP_iastore]); + } + + table[OP_pop] = PopInstruction.make(1); + table[OP_dup] = DupInstruction.make(1, 0); + table[OP_dup_x1] = DupInstruction.make(1, 1); + table[OP_swap] = SwapInstruction.make(); + + for (int i = OP_iadd; i <= OP_drem; i++) { + table[i] = BinaryOpInstruction.make(indexedTypes[(i - OP_iadd) % 4], BinaryOpInstruction.Operator.values()[(i - OP_iadd) / 4]); + } + for (int i = OP_ineg; i <= OP_dneg; i++) { + table[i] = UnaryOpInstruction.make(indexedTypes[i - OP_ineg], UnaryOpInstruction.Operator.NEG); + } + for (int i = OP_ishl; i <= OP_lushr; i++) { + table[i] = ShiftInstruction.make(indexedTypes[(i - OP_ishl) % 2], ShiftInstruction.Operator.values()[(i - OP_ishl) / 2]); + } + for (int i = OP_iand; i <= OP_lxor; i++) { + table[i] = BinaryOpInstruction.make(indexedTypes[(i - OP_iand) % 2], BinaryOpInstruction.Operator.values()[BinaryOpInstruction.Operator.AND.ordinal() + (i - OP_iand) / 2]); + } + + for (int i = OP_i2l; i <= OP_d2f; i++) { + table[i] = ConversionInstruction.make(indexedTypes[(i - OP_i2l) / 3], indexedTypes[skip((i - OP_i2l) % 3, (i - OP_i2l) / 3)]); + } + for (int i = OP_i2b; i <= OP_i2s; i++) { + table[i] = ConversionInstruction.make(TYPE_int, indexedTypes[5 + (i - OP_i2b)]); + } + + table[OP_lcmp] = ComparisonInstruction.make(TYPE_long, ComparisonInstruction.Operator.CMP); + for (int i = OP_fcmpl; i <= OP_dcmpg; i++) { + table[i] = ComparisonInstruction.make(indexedTypes[2 + (i - OP_fcmpl) / 2], ComparisonInstruction.Operator.values()[ComparisonInstruction.Operator.CMPL.ordinal() + (i - OP_fcmpl) % 2]); + } + + for (int i = OP_ireturn; i <= OP_areturn; i++) { + table[i] = ReturnInstruction.make(indexedTypes[i - OP_ireturn]); + } + table[OP_return] = ReturnInstruction.make(TYPE_void); + + table[OP_athrow] = ThrowInstruction.make(); + + table[OP_monitorenter] = MonitorInstruction.make(true); + table[OP_monitorexit] = MonitorInstruction.make(false); + + table[OP_arraylength] = ArrayLengthInstruction.make(); + + return table; + } + + private static final Instruction makeZero = ConstantInstruction.make(0); + + // Holds the result of decoding + private Instruction[] instructions; + private ExceptionHandler[][] handlers; + private int[] instructionsToBytecodes; + private ConstantPoolReader constantPool; + + // Holds the input to decode + private byte[] code; + private int[] rawHandlers; + + // Temporary working data + private int[] decodedOffset; + private byte[] decodedSize; + private ArrayList decoded; + private int[] belongsToSub; + private int[] JSRs; + private RetInfo[] retInfo; + + /** + * This constructor is only supposed to be used by subclasses. + * + * @param code + * the bytecodes for a method as per JVM spec + * @param rawHandlers + * flattened array of (startPC, endPC, targetPC, classIndex) tuples + * defined as per the JVM spec + */ + protected Decoder(byte[] code, int[] rawHandlers, ConstantPoolReader cp) { + this.code = code; + this.rawHandlers = rawHandlers; + this.constantPool = cp; + } + + public ConstantPoolReader getConstantPool() { + return constantPool; + } + + private int decodeShort(int index) { + return (code[index] << 8) | (code[index + 1] & 0xFF); + } + + private int decodeUShort(int index) { + return ((code[index] & 0xFF) << 8) | (code[index + 1] & 0xFF); + } + + private int decodeInt(int index) { + return (code[index] << 24) | ((code[index + 1] & 0xFF) << 16) | ((code[index + 2] & 0xFF) << 8) | (code[index + 3] & 0xFF); + } + + private Instruction makeConstantPoolLoad(int index) throws InvalidBytecodeException { + ConstantInstruction ci = ConstantInstruction.make(constantPool, index); + if (ci == null) { + throw new InvalidBytecodeException("Constant pool item at index " + index + " (type " + + constantPool.getConstantPoolItemType(index) + ") cannot be loaded"); + } + return ci; + } + + private static int elemCount(byte[] stack, int stackPtr) throws InvalidBytecodeException { + if (stackPtr < 0) { + throw new InvalidBytecodeException("Stack underflow"); + } + + if (stack[stackPtr] == 2) { + return 1; + } else { + if (stackPtr < 1) { + throw new InvalidBytecodeException("Stack underflow"); + } + + if (stack[stackPtr - 1] != 1) { + throw new InvalidBytecodeException("Trying to manipulate a pair of " + "one-word items but one of them is two words"); + } + + return 2; + } + } + + private String getPrimitiveType(int t) throws InvalidBytecodeException { + switch (t) { + case T_BOOLEAN: + return TYPE_boolean; + case T_CHAR: + return TYPE_char; + case T_FLOAT: + return TYPE_float; + case T_DOUBLE: + return TYPE_double; + case T_BYTE: + return TYPE_byte; + case T_SHORT: + return TYPE_short; + case T_INT: + return TYPE_int; + case T_LONG: + return TYPE_long; + default: + throw new InvalidBytecodeException("Unknown primitive type " + t); + } + } + + private static class RetInfo { + int sub; + int retVar; + int stackLen; + byte[] stackWords; + + RetInfo(int sub, int retVar, int stackLen, byte[] stackWords) { + this.sub = sub; + this.retVar = retVar; + this.stackLen = stackLen; + this.stackWords = stackWords; + } + } + + private boolean doesSubroutineReturn(int sub) { + for (int j = 0; j < retInfo.length; j++) { + if (retInfo[j] != null && retInfo[j].sub == sub) { + return true; + } + } + return false; + } + + private int findReturnToVar(int v, int addr, boolean[] visited) throws InvalidBytecodeException { + while (true) { + if (visited[addr]) { + return 0; + } else if (retInfo[addr] != null && retInfo[addr].retVar == v) { + return addr; + } else { + int offset = decodedOffset[addr]; + + if (offset == UNSEEN) { + return 0; + } + + int size = decodedSize[addr]; + Instruction instr = null; + + visited[addr] = true; + + for (int j = 0; j < rawHandlers.length; j += 4) { + if (rawHandlers[j] <= addr && addr < rawHandlers[j + 1]) { + int handlerAddr = rawHandlers[j + 2]; + + if (decodedOffset[handlerAddr] < 0) { + byte[] stackWords = new byte[code.length * 2]; + + decodeAt(handlerAddr, 1, stackWords); + } + + int r = findReturnToVar(v, handlerAddr, visited); + if (r != 0) { + return r; + } + } + } + + // If there's a JSR here, see if it ever returns. If it does not + // then this instruction does not fall through and so we should + // stop searching. + if (JSRs[addr] != 0) { + if (!doesSubroutineReturn(JSRs[addr])) { + return 0; + } + } else { + for (int j = 0; j < size; j++) { + instr = decoded.get(offset + j); + if (instr instanceof StoreInstruction && ((StoreInstruction) instr).getVarIndex() == v) { + return 0; + } + + int[] targets = instr.getBranchTargets(); + for (int k = 0; k < targets.length; k++) { + if (targets[k] >= 0) { + int r = findReturnToVar(v, targets[k], visited); + if (r != 0) { + return r; + } + } + } + } + + if (instr != null && !instr.isFallThrough()) { + return 0; + } + } + + do { + addr++; + } while (decodedOffset[addr] == INSIDE_INSTRUCTION); + } + } + } + + /** + * Locate an instruction that returns from this subroutine; return 0 if one + * cannot be found. + */ + private int findReturn(int subAddr) throws InvalidBytecodeException { + if (decodedSize[subAddr] < 1) { + throw new InvalidBytecodeException("Subroutine at " + subAddr + " does not start with an astore or pop instruction"); + } + Instruction instr = decoded.get(decodedOffset[subAddr]); + + if (instr instanceof PopInstruction) { + // this subroutine can't return + return 0; + } + + if (!(instr instanceof StoreInstruction)) { + throw new InvalidBytecodeException("Subroutine at " + subAddr + " does not start with an astore or pop instruction"); + } + + int localIndex = ((StoreInstruction) instr).getVarIndex(); + + do { + subAddr++; + } while (decodedOffset[subAddr] == INSIDE_INSTRUCTION); + + return findReturnToVar(localIndex, subAddr, new boolean[code.length]); + } + + private void decodeSubroutine(int jsrAddr, int retToAddr, int subAddr, int stackLen, byte[] stackWords) + throws InvalidBytecodeException { + if (JSRs == null) { + JSRs = new int[code.length]; + retInfo = new RetInfo[code.length]; + } + + JSRs[jsrAddr] = subAddr; + + if (decodedOffset[subAddr] < 0) { + stackWords[stackLen] = 1; + stackLen++; + + decodeAt(subAddr, stackLen, stackWords); + } + + int retAddr = findReturn(subAddr); + if (retAddr > 0) { + RetInfo r = retInfo[retAddr]; + r.sub = subAddr; + decodeAt(retToAddr, r.stackLen, (byte[]) r.stackWords.clone()); + } + } + + private void assignReachablesToSubroutine(int addr, int sub) { + + while (belongsToSub[addr] < 0) { + int size = decodedSize[addr]; + + belongsToSub[addr] = sub; + + for (int j = 0; j < rawHandlers.length; j += 4) { + if (rawHandlers[j] <= addr && addr < rawHandlers[j + 1]) { + assignReachablesToSubroutine(rawHandlers[j + 2], sub); + } + } + + Instruction instr = null; + if (size > 0 && JSRs[addr] == 0) { + int offset = decodedOffset[addr]; + instr = decoded.get(offset + size - 1); + int[] targets = instr.getBranchTargets(); + for (int k = 0; k < targets.length; k++) { + if (targets[k] >= 0) { + // only chase real gotos; ignore rets + assignReachablesToSubroutine(targets[k], sub); + } + } + } + + if (instr != null && !instr.isFallThrough()) { + return; + } + if (JSRs[addr] != 0 && !doesSubroutineReturn(JSRs[addr])) { + return; + } + + do { + addr++; + } while (decodedOffset[addr] < 0); + } + } + + private void assignSubroutine(int sub) { + assignReachablesToSubroutine(sub, sub); + + for (int i = 0; i < belongsToSub.length; i++) { + if (JSRs[i] > 0 && belongsToSub[i] == sub && belongsToSub[JSRs[i]] < 0) { + assignSubroutine(JSRs[i]); + } + } + } + + private void computeSubroutineMap() { + belongsToSub = new int[code.length]; + + for (int i = 0; i < belongsToSub.length; i++) { + belongsToSub[i] = -1; + } + + assignSubroutine(0); + } + + private int decodeBytecodeInstruction(int index, int stackLen, byte[] stackWords) throws InvalidBytecodeException { + int opcode = code[index] & 0xFF; + + Instruction i = simpleInstructions[opcode]; + if (i != null) { + decoded.add(i); + return index + 1; + } + + boolean wide = false; + + while (true) { + index++; + + switch (opcode) { + case OP_nop: + break; + case OP_bipush: + i = ConstantInstruction.make(code[index]); + index++; + break; + case OP_sipush: + i = ConstantInstruction.make(decodeShort(index)); + index += 2; + break; + case OP_ldc: + i = makeConstantPoolLoad(code[index] & 0xFF); + index++; + break; + case OP_ldc_w: + i = makeConstantPoolLoad(decodeShort(index)); + index += 2; + break; + case OP_ldc2_w: + i = makeConstantPoolLoad(decodeShort(index)); + index += 2; + break; + case OP_iload: + case OP_lload: + case OP_fload: + case OP_dload: + case OP_aload: + i = LoadInstruction.make(indexedTypes[opcode - OP_iload], wide ? decodeUShort(index) : (code[index] & 0xFF)); + index += wide ? 2 : 1; + break; + case OP_istore: + case OP_lstore: + case OP_fstore: + case OP_dstore: + case OP_astore: + i = StoreInstruction.make(indexedTypes[opcode - OP_istore], wide ? decodeUShort(index) : (code[index] & 0xFF)); + index += wide ? 2 : 1; + break; + case OP_pop2: + i = PopInstruction.make(elemCount(stackWords, stackLen - 1)); + break; + case OP_dup_x2: + i = DupInstruction.make(1, elemCount(stackWords, stackLen - 2)); + break; + case OP_dup2: + i = DupInstruction.make(elemCount(stackWords, stackLen - 1), 0); + break; + case OP_dup2_x1: + i = DupInstruction.make(elemCount(stackWords, stackLen - 1), 1); + break; + case OP_dup2_x2: + i = DupInstruction.make(elemCount(stackWords, stackLen - 1), elemCount(stackWords, stackLen - 2)); + break; + case OP_iinc: { + int v = wide ? decodeUShort(index) : (code[index] & 0xFF); + int c = wide ? decodeShort(index + 2) : code[index + 1]; + + decoded.add(LoadInstruction.make(TYPE_int, v)); + decoded.add(ConstantInstruction.make(c)); + decoded.add(BinaryOpInstruction.make(TYPE_int, Operator.ADD)); + i = StoreInstruction.make(TYPE_int, v); + index += wide ? 4 : 2; + break; + } + case OP_ifeq: + case OP_ifne: + case OP_iflt: + case OP_ifle: + case OP_ifgt: + case OP_ifge: + decoded.add(makeZero); + i = ConditionalBranchInstruction.make(TYPE_int, ConditionalBranchInstruction.Operator.values()[opcode - OP_ifeq], (index - 1) + decodeShort(index)); + index += 2; + break; + case OP_if_icmpeq: + case OP_if_icmpne: + case OP_if_icmplt: + case OP_if_icmple: + case OP_if_icmpgt: + case OP_if_icmpge: + i = ConditionalBranchInstruction.make((short) opcode, (index - 1) + decodeShort(index)); + index += 2; + break; + case OP_if_acmpeq: + case OP_if_acmpne: + i = ConditionalBranchInstruction.make(TYPE_Object, ConditionalBranchInstruction.Operator.values()[opcode - OP_if_acmpeq], (index - 1) + + decodeShort(index)); + index += 2; + break; + case OP_goto: + i = GotoInstruction.make((index - 1) + decodeShort(index)); + index += 2; + break; + case OP_jsr: { + index += 2; + break; + } + case OP_jsr_w: { + index += 4; + break; + } + case OP_ret: + int v = wide ? decodeUShort(index) : (code[index] & 0xFF); + i = GotoInstruction.make(-1 - v); + + if (retInfo == null) { + throw new InvalidBytecodeException("'ret' outside of subroutine"); + } + retInfo[index - (wide ? 2 : 1)] = new RetInfo(-1, v, stackLen, stackWords); + + index += wide ? 2 : 1; + break; + case OP_tableswitch: { + int start = index - 1; + while ((index & 3) != 0) { + index++; + } + int def = start + decodeInt(index); + int low = decodeInt(index + 4); + int high = decodeInt(index + 8); + int[] t = new int[(high - low + 1) * 2]; + + for (int j = 0; j < t.length; j += 2) { + t[j] = j / 2 + low; + t[j + 1] = start + decodeInt(index + 12 + j * 2); + } + i = SwitchInstruction.make(t, def); + index += 12 + (high - low + 1) * 4; + break; + } + case OP_lookupswitch: { + int start = index - 1; + while ((index & 3) != 0) { + index++; + } + int def = start + decodeInt(index); + int n = decodeInt(index + 4); + int[] t = new int[n * 2]; + + for (int j = 0; j < t.length; j += 2) { + t[j] = decodeInt(index + 8 + j * 4); + t[j + 1] = start + decodeInt(index + 12 + j * 4); + } + i = SwitchInstruction.make(t, def); + index += 8 + n * 8; + break; + } + case OP_getstatic: + case OP_getfield: { + int f = decodeUShort(index); + i = GetInstruction.make(constantPool, f, opcode == OP_getstatic); + index += 2; + break; + } + case OP_putstatic: + case OP_putfield: { + int f = decodeUShort(index); + i = PutInstruction.make(constantPool, f, opcode == OP_putstatic); + index += 2; + break; + } + case OP_invokevirtual: + case OP_invokespecial: + case OP_invokestatic: { + int m = decodeUShort(index); + i = InvokeInstruction.make(constantPool, m, opcode); + index += 2; + break; + } + case OP_invokeinterface: { + int m = decodeUShort(index); + i = InvokeInstruction.make(constantPool, m, opcode); + index += 4; + break; + } + case OP_new: + i = NewInstruction.make(constantPool.getConstantPoolClassType(decodeUShort(index)), 0); + index += 2; + break; + case OP_newarray: + i = NewInstruction.make(Util.makeArray(getPrimitiveType(code[index])), 1); + index++; + break; + case OP_anewarray: + i = NewInstruction.make(Util.makeArray(constantPool.getConstantPoolClassType(decodeUShort(index))), 1); + index += 2; + break; + case OP_checkcast: + i = CheckCastInstruction.make(constantPool.getConstantPoolClassType(decodeUShort(index))); + index += 2; + break; + case OP_instanceof: + i = InstanceofInstruction.make(constantPool.getConstantPoolClassType(decodeUShort(index))); + index += 2; + break; + case OP_wide: + wide = true; + opcode = code[index] & 0xFF; + continue; + case OP_multianewarray: + i = NewInstruction.make(constantPool.getConstantPoolClassType(decodeUShort(index)), code[index + 2] & 0xFF); + index += 3; + break; + case OP_ifnull: + case OP_ifnonnull: + decoded.add(ConstantInstruction.make(TYPE_Object, null)); + i = ConditionalBranchInstruction.make(TYPE_Object, ConditionalBranchInstruction.Operator.values()[opcode - OP_ifnull], (index - 1) + decodeShort(index)); + index += 2; + break; + case OP_goto_w: + i = GotoInstruction.make((index - 1) + decodeInt(index)); + index += 4; + break; + default: + throw new InvalidBytecodeException("Unknown opcode " + opcode); + } + + break; + } + + if (i != null) { + decoded.add(i); + } + + return index; + } + + private int applyInstructionToStack(Instruction i, int stackLen, byte[] stackWords) throws InvalidBytecodeException { + stackLen -= i.getPoppedCount(); + + if (stackLen < 0) { + throw new InvalidBytecodeException("Stack underflow"); + } + + if (i instanceof DupInstruction) { + DupInstruction d = (DupInstruction) i; + int delta = d.getDelta(); + int size = d.getSize(); + + System.arraycopy(stackWords, stackLen + delta, stackWords, stackLen + size + delta, size); + System.arraycopy(stackWords, stackLen, stackWords, stackLen + size, delta); + System.arraycopy(stackWords, stackLen + size + delta, stackWords, stackLen, size); + stackLen += size * 2 + delta; + } else if (i instanceof SwapInstruction) { + if (stackWords[stackLen] != stackWords[stackLen + 1]) { + throw new Error("OP_swap must always be swapping the same size, 1"); + } + stackLen += 2; + } else { + byte pushedWords = i.getPushedWordSize(); + if (pushedWords > 0) { + stackWords[stackLen] = pushedWords; + stackLen++; + } + } + + return stackLen; + } + + private void decodeAt(int index, int stackLen, byte[] stackWords) throws InvalidBytecodeException { + if (index < 0 || index >= decodedOffset.length) { + throw new InvalidBytecodeException(index, "Branch index " + index + " out of range"); + } + + while (decodedOffset[index] < 0) { + int s = decoded.size(); + + decodedOffset[index] = s; + + int newIndex; + + try { + newIndex = decodeBytecodeInstruction(index, stackLen, stackWords); + int instrCount = decoded.size() - s; + + decodedSize[index] = (byte) instrCount; + + // mark invalid offsets + for (int i = index + 1; i < newIndex; i++) { + decodedOffset[i] = INSIDE_INSTRUCTION; + } + + if (instrCount > 0) { + for (int i = s; i < s + instrCount; i++) { + stackLen = applyInstructionToStack(decoded.get(i), stackLen, stackWords); + } + + Instruction instr = decoded.get(s + instrCount - 1); + int[] targets = instr.getBranchTargets(); + + for (int i = 0; i < targets.length; i++) { + int t = targets[i]; + + if (t >= 0) { + decodeAt(t, stackLen, (byte[]) stackWords.clone()); + } + } + + if (!instr.isFallThrough()) { + return; + } + } else { // possibly the jsr case + int jIndex = index; + int opcode = code[jIndex] & 0xFF; + if (opcode == OP_wide) { + jIndex++; + opcode = code[jIndex] & 0xFF; + } + + if (opcode == OP_jsr || opcode == OP_jsr_w) { + jIndex++; + int offset = opcode == OP_jsr_w ? decodeInt(jIndex) : decodeShort(jIndex); + + decoded.add(GotoInstruction.make(0)); + decodedSize[index] = 1; + + decodeSubroutine(index, newIndex, index + offset, stackLen, stackWords); + return; + } + } + } catch (InvalidBytecodeException ex) { + ex.setIndex(index); + throw ex; + } catch (Error ex) { + System.err.println("Fatal error at index " + index); + throw ex; + } catch (RuntimeException ex) { + System.err.println("Fatal error at index " + index); + throw ex; + } + + index = newIndex; + + if (index >= decodedOffset.length) { + throw new InvalidBytecodeException(index, "Fell off end of bytecode array"); + } + } + } + + /** + * This exception is thrown when the Decoder detects invalid incoming bytecode + * (code that would not pass the Java verifier). We don't guarantee to perform + * full verification in the Decoder, however. + */ + public static class InvalidBytecodeException extends Exception { + + private static final long serialVersionUID = -8807125136613458111L; + private int index; + + InvalidBytecodeException(String s) { + super(s); + index = -1; + } + + InvalidBytecodeException(int i, String s) { + super(s); + index = i; + } + + void setIndex(int i) { + if (index < 0) { + index = i; + } + } + + /** + * @return the offset of the bytecode instruction deemed to be invalid + */ + public int getIndex() { + return index; + } + } + + private ExceptionHandler[] makeHandlers(int i, int[] addrMap) { + int numHandlers = 0; + for (int j = 0; j < rawHandlers.length; j += 4) { + if (rawHandlers[j] <= i && i < rawHandlers[j + 1]) { + numHandlers++; + } + } + + return makeHandlers(i, numHandlers, addrMap); + } + + private ExceptionHandler[] makeHandlers(int i, int numHandlers, int[] addrMap) { + if (numHandlers == 0) { + return noHandlers; + } else { + ExceptionHandler[] hs = new ExceptionHandler[numHandlers]; + numHandlers = 0; + for (int j = 0; j < rawHandlers.length; j += 4) { + if (rawHandlers[j] <= i && i < rawHandlers[j + 1]) { + int classIndex = rawHandlers[j + 3]; + String catchClass = classIndex == 0 ? null : constantPool.getConstantPoolClassType(classIndex); + + hs[numHandlers] = new ExceptionHandler(addrMap[rawHandlers[j + 2]], catchClass); + numHandlers++; + } + } + return hs; + } + } + + private int computeSubroutineLength(int sub) { + int len = 1; // extra instruction for "push null" + + for (int i = sub; i < belongsToSub.length; i++) { + if (belongsToSub[i] == sub) { + len += decodedSize[i]; + if (JSRs[i] > 0) { + len += computeSubroutineLength(JSRs[i]); + } + } + } + + return len; + } + + private int appendSubroutineCode(int callSite, int newCodeIndex, int[] callerMap) { + instructions[callerMap[callSite]] = GotoInstruction.make(newCodeIndex); + + instructions[newCodeIndex] = ConstantInstruction.make(TYPE_Object, null); + newCodeIndex++; + + int subStart = newCodeIndex; + int[] map = (int[]) callerMap.clone(); + int sub = JSRs[callSite]; + + // emit the subroutine code + for (int i = sub; i < belongsToSub.length; i++) { + if (belongsToSub[i] == sub) { + int s = decodedSize[i]; + int offset = decodedOffset[i]; + + map[i] = newCodeIndex; + + for (int j = 0; j < s; j++) { + Instruction instr = decoded.get(offset + j); + instructions[newCodeIndex] = instr; + instructionsToBytecodes[newCodeIndex] = i; + newCodeIndex++; + } + } + } + + // fix up branch targets within emitted subroutine + for (int i = subStart; i < newCodeIndex; i++) { + Instruction instr = instructions[i]; + if (instr instanceof GotoInstruction && ((GotoInstruction) instr).getLabel() < 0) { + // fix up 'ret' instruction to branch back to return address + instructions[i] = GotoInstruction.make(callerMap[callSite] + 1); + } else { + instructions[i] = instr.redirectTargets(map); + } + handlers[i] = makeHandlers(instructionsToBytecodes[i], map); + } + + // extend handlers to cover the fake "push null" + handlers[subStart - 1] = handlers[subStart]; + + // resolve callee subroutines + for (int i = sub; i < belongsToSub.length; i++) { + if (belongsToSub[i] == sub && JSRs[i] > 0) { + newCodeIndex = appendSubroutineCode(i, newCodeIndex, map); + } + } + + return newCodeIndex; + } + + /** + * Perform the decoding. + * + * @throws InvalidBytecodeException + * the incoming code is invalid and would fail Java bytecode + * verification + */ + final public void decode() throws InvalidBytecodeException { + byte[] stackWords = new byte[code.length * 2]; + + decoded = new ArrayList(); + decodedOffset = new int[code.length]; + for (int i = 0; i < decodedOffset.length; i++) { + decodedOffset[i] = UNSEEN; + } + decodedSize = new byte[code.length]; + + decodeAt(0, 0, stackWords); + // Decode code that's only reachable through exception handlers + for (int i = 0; i < rawHandlers.length; i += 4) { + stackWords[0] = 1; + decodeAt(rawHandlers[i + 2], 1, stackWords); + } + + if (retInfo != null) { + computeSubroutineMap(); + retInfo = null; + } + + int instructionsLen = decoded.size(); + + if (belongsToSub != null) { + for (int i = 0; i < belongsToSub.length; i++) { + if (belongsToSub[i] == 0) { + if (JSRs[i] > 0) { + instructionsLen += computeSubroutineLength(JSRs[i]); + } + } else if (belongsToSub[i] > 0) { + instructionsLen -= decodedSize[i]; + } + } + } + + instructions = new Instruction[instructionsLen]; + instructionsToBytecodes = new int[instructionsLen]; + handlers = new ExceptionHandler[instructionsLen][]; + + // shuffle decoded instructions into method order + int p = 0; + for (int i = 0; i < decodedOffset.length; i++) { + int offset = decodedOffset[i]; + + if (offset >= 0 && (belongsToSub == null || belongsToSub[i] == 0)) { + decodedOffset[i] = p; + + int s = decodedSize[i]; + for (int j = 0; j < s; j++) { + instructions[p] = decoded.get(offset + j); + instructionsToBytecodes[p] = i; + p++; + } + } + } + + // fix up instructions to refer to the instruction vector instead of + // bytecode offsets + for (int i = 0; i < p; i++) { + instructions[i] = instructions[i].redirectTargets(decodedOffset); + } + + // emit subroutines + if (JSRs != null) { + for (int i = 0; i < JSRs.length; i++) { + if (JSRs[i] > 0 && belongsToSub[i] == 0) { + p = appendSubroutineCode(i, p, decodedOffset); + } + } + } + + // generate exception handlers + if (rawHandlers.length > 0) { + ExceptionHandler[] hs = null; + int handlersValidBefore = -1; + + p = 0; + for (int i = 0; i < decodedOffset.length; i++) { + if (decodedOffset[i] >= 0 && (belongsToSub == null || belongsToSub[i] == 0)) { + if (i >= handlersValidBefore) { + // We just crossed a handler range boundary + // compute new exception handler array + int numHandlers = 0; + handlersValidBefore = Integer.MAX_VALUE; + for (int j = 0; j < rawHandlers.length; j += 4) { + if (rawHandlers[j] <= i) { + if (i < rawHandlers[j + 1]) { + numHandlers++; + handlersValidBefore = Math.min(handlersValidBefore, rawHandlers[j + 1]); + } + } else { + handlersValidBefore = Math.min(handlersValidBefore, rawHandlers[j]); + } + } + + hs = makeHandlers(i, numHandlers, decodedOffset); + } + + int s = decodedSize[i]; + for (int j = 0; j < s; j++) { + handlers[p] = hs; + p++; + } + } + } + } else { + for (int i = 0; i < handlers.length; i++) { + handlers[i] = noHandlers; + } + } + + decoded = null; + decodedOffset = null; + decodedSize = null; + belongsToSub = null; + JSRs = null; + } + + /** + * Get the decoded instructions. + * + * @return array of decoded instructions + */ + final public Instruction[] getInstructions() { + if (instructions == null) { + throw new Error("Call decode() before calling getInstructions()"); + } + return instructions; + } + + /** + * Get the decoded exception handlers. + * + * @return array of exception handler lists + */ + final public ExceptionHandler[][] getHandlers() { + if (handlers == null) { + throw new Error("Call decode() before calling getHandlers()"); + } + return handlers; + } + + /** + * Get the mapping between instructions and input bytecodes. + * + * @return an array m such that m[i] is the offset of the bytecode instruction + * which gave rise to the Instruction referenced in the instructions + * array at offset i + */ + final public int[] getInstructionsToBytecodes() { + if (instructionsToBytecodes == null) { + throw new Error("Call decode() before calling getInstructionsToBytecodes()"); + } + return instructionsToBytecodes; + } +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/Disassembler.java b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/Disassembler.java new file mode 100644 index 000000000..938eb74e0 --- /dev/null +++ b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/Disassembler.java @@ -0,0 +1,60 @@ +/******************************************************************************* + * 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.shrikeBT; + +import java.io.IOException; +import java.io.Writer; + +/** + * This is a very simple component to disassemble a ShrikeBT method. The + * disassembly is just the list of ShrikeBT instructions, annotated with + * exception handler blocks and the mapping back to the original bytecodes. + */ +public class Disassembler { + private Instruction[] instructions; + private ExceptionHandler[][] handlers; + private int[] instructionsToBytecodes; + + /** + * Create a disassembler for a method. + */ + public Disassembler(Instruction[] instructions, ExceptionHandler[][] handlers, int[] instructionsToBytecodes) { + this.instructions = instructions; + this.handlers = handlers; + this.instructionsToBytecodes = instructionsToBytecodes; + } + + /** + * Create a disassembler for a method. + */ + public Disassembler(MethodData data) { + this(data.getInstructions(), data.getHandlers(), data.getInstructionsToBytecodes()); + } + + /** + * Write the disassembly to a stream. Each line is prefixed with 'prefix'. + */ + public void disassembleTo(String prefix, Writer w) throws IOException { + for (int j = 0; j < instructions.length; j++) { + w.write(prefix + j + ": " + instructions[j] + " (" + instructionsToBytecodes[j] + ")\n"); + for (int k = 0; k < handlers[j].length; k++) { + w.write(prefix + " Handles " + handlers[j][k].catchClass + " at " + handlers[j][k].handler + "\n"); + } + } + } + + /** + * Write the disassembly to a stream. + */ + public void disassembleTo(Writer w) throws IOException { + disassembleTo("", w); + } +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/DupInstruction.java b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/DupInstruction.java new file mode 100644 index 000000000..72eae5a5d --- /dev/null +++ b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/DupInstruction.java @@ -0,0 +1,106 @@ +/******************************************************************************* + * 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.shrikeBT; + +/** + * This class represents dup instructions. There are two kinds of dup + * instructions, dup and dup_x1: + * + * dup: a::rest => a::a::rest dup_x1: a::b::rest => a::b::a::rest + */ +public final class DupInstruction extends Instruction { + private int size; + private byte delta; + + protected DupInstruction(byte size, byte delta) { + this.size = size; + this.delta = delta; + } + + private final static DupInstruction[] preallocated = preallocate(); + + private static DupInstruction[] preallocate() { + DupInstruction[] r = new DupInstruction[9]; + + for (int i = 0; i < r.length; i++) { + r[i] = new DupInstruction((byte) (i / 3), (byte) (i % 3)); + } + return r; + } + + /** + * DupInstructions with size or delta 2 might cause code generation failures + * when the working stack contains long or double values, when these + * DupInstructions cannot be easily translated into Java bytecode + * instructions. For safety, avoid using DupInstructions with size or delta 2. + * + * Don't create these outside the shrikeBT decoder. + */ + static DupInstruction make(int size, int delta) { + if (size < 0 || size > 2) { + throw new IllegalArgumentException("Invalid dup size: " + size); + } + if (delta < 0 || delta > 2) { + throw new IllegalArgumentException("Invalid dup delta: " + delta); + } + return preallocated[size * 3 + delta]; + } + + /** + * @param delta + * 0 for dup, 1 for dup_x1 + */ + public static DupInstruction make(int delta) { + if (delta < 0 || delta > 1) { + throw new IllegalArgumentException("Invalid dup delta: " + delta); + } + return make(1, delta); + } + + public boolean equals(Object o) { + if (o instanceof DupInstruction) { + DupInstruction i = (DupInstruction) o; + return i.size == size && i.delta == delta; + } else { + return false; + } + } + + public int getSize() { + return size; + } + + public int getDelta() { + return delta; + } + + public int hashCode() { + return size + 8431890 + 10 * delta; + } + + public int getPoppedCount() { + return size + delta; + } + + public String toString() { + return "Dup(" + size + "," + delta + ")"; + } + + public void visit(Visitor v) { + v.visitDup(this); + } + /* (non-Javadoc) + * @see com.ibm.domo.cfg.IInstruction#isPEI() + */ + public boolean isPEI() { + return false; + } +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/ExceptionHandler.java b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/ExceptionHandler.java new file mode 100644 index 000000000..f4888c5c5 --- /dev/null +++ b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/ExceptionHandler.java @@ -0,0 +1,84 @@ +/******************************************************************************* + * 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.shrikeBT; + +/** + * An ExceptionHandler represents a single handler covering a single + * instruction. It simply tells us what kind of exception to catch and where to + * dispatch the exception to. + * + * ExceptionHandlers are immutable. It is quite legal to save a reference to an + * exception handler and use it in any other context. We also treat arrays of + * ExceptionHandlers as immutable. Therefore the following code can be used to + * build an exception handler table that specifies two handlers covering an + * entire block of code: + * + *
                              + * 
                              + *  ExceptionHandler[] hs = {
                              + *    new ExceptionHandler(110, "Ljava.lang.NullPointerException;"),
                              + *    new ExceptionHandler(220, "Ljava.io.IOException;");
                              + *  };
                              + *  for (int i = 0; i < 100; i++) {
                              + *    handlers[i] = hs;
                              + *  }
                              + * 
                              + */ +final public class ExceptionHandler { + int handler; + String catchClass; + + /** + * @param handler + * the label for the handler code + * @param catchClass + * the type of exception that should be caught (in JVM format), or + * null if all exceptions should be caught (as with 'finally') + */ + public ExceptionHandler(int handler, String catchClass) { + this.handler = handler; + this.catchClass = catchClass; + } + + /** + * @return the label of the handler code + */ + public int getHandler() { + return handler; + } + + /** + * @return the type of exceptions to be caught, or null if all exceptions + * should be caught + */ + public String getCatchClass() { + return catchClass; + } + + public boolean equals(ExceptionHandler h) { + return h.handler == handler && (catchClass == null ? h.catchClass == null : catchClass.equals(h.catchClass)); + } + + /* (non-Javadoc) + * @see java.lang.Object#hashCode() + */ + public int hashCode() { + return 1069 * handler + ((catchClass == null) ? 0 : catchClass.hashCode()); + } + + public boolean equals(Object o) { + if (o instanceof ExceptionHandler) { + return equals((ExceptionHandler) o); + } else { + return false; + } + } +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/GetInstruction.java b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/GetInstruction.java new file mode 100644 index 000000000..b58053b63 --- /dev/null +++ b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/GetInstruction.java @@ -0,0 +1,145 @@ +/******************************************************************************* + * 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.shrikeBT; + +/** + * This class represents get and getstatic instructions. + */ +public class GetInstruction extends Instruction { + protected String type; + protected String classType; + protected String fieldName; + + GetInstruction(short opcode, String type, String classType, String fieldName) { + this.opcode = opcode; + this.type = type; + this.classType = classType; + this.fieldName = fieldName; + } + + ConstantPoolReader getLazyConstantPool() { + return null; + } + + final static class Lazy extends GetInstruction { + private ConstantPoolReader cp; + private int index; + + Lazy(short opcode, ConstantPoolReader cp, int index) { + super(opcode, null, null, null); + this.index = index; + this.cp = cp; + } + + ConstantPoolReader getLazyConstantPool() { + return cp; + } + + int getCPIndex() { + return index; + } + + public String getClassType() { + if (classType == null) { + classType = cp.getConstantPoolMemberClassType(index); + } + return classType; + } + + public String getFieldName() { + if (fieldName == null) { + fieldName = cp.getConstantPoolMemberName(index); + } + return fieldName; + } + + public String getFieldType() { + if (type == null) { + type = cp.getConstantPoolMemberType(index); + } + return type; + } + } + + static GetInstruction make(ConstantPoolReader cp, int index, boolean isStatic) { + return new Lazy(isStatic ? OP_getstatic : OP_getfield, cp, index); + } + + public static GetInstruction make(String type, String className, String fieldName, boolean isStatic) { + if (type == null) { + throw new NullPointerException("type must not be null"); + } + if (className == null) { + throw new NullPointerException("className must not be null"); + } + if (fieldName == null) { + throw new NullPointerException("fieldName must not be null"); + } + return new GetInstruction(isStatic ? OP_getstatic : OP_getfield, type, className, fieldName); + } + + final public boolean equals(Object o) { + if (o instanceof GetInstruction) { + GetInstruction i = (GetInstruction) o; + return i.getFieldType().equals(getFieldType()) && i.getClassType().equals(getClassType()) + && i.getFieldName().equals(getFieldName()) && i.opcode == opcode; + } else { + return false; + } + } + + public String getClassType() { + return classType; + } + + public String getFieldName() { + return fieldName; + } + + public String getFieldType() { + return type; + } + + final public boolean isStatic() { + return opcode == OP_getstatic; + } + + final public int hashCode() { + return getClassType().hashCode() + 11113 * getFieldType().hashCode() + 398011 * getFieldName().hashCode() + opcode; + } + + final public int getPoppedCount() { + return isStatic() ? 0 : 1; + } + + final public String getPushedType(String[] types) { + return getFieldType(); + } + + final public byte getPushedWordSize() { + return Util.getWordSize(getFieldType()); + } + + public String toString() { + return "Get(" + getFieldType() + "," + (isStatic() ? "STATIC" : "NONSTATIC") + "," + getClassType() + "," + getFieldName() + + ")"; + } + + public void visit(Visitor v) { + v.visitGet(this); + } + /* (non-Javadoc) + * @see com.ibm.domo.cfg.IInstruction#isPEI() + */ + public boolean isPEI() { + return true; + } +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/GotoInstruction.java b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/GotoInstruction.java new file mode 100644 index 000000000..2c1362ab5 --- /dev/null +++ b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/GotoInstruction.java @@ -0,0 +1,85 @@ +/******************************************************************************* + * 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.shrikeBT; + +/** + * This class represents goto and goto_w instructions. + */ +public final class GotoInstruction extends Instruction { + private int[] label; + + protected GotoInstruction(int label) { + int[] l = { label }; + this.label = l; + this.opcode = OP_goto; + } + + private final static GotoInstruction[] preallocated = preallocate(); + + private static GotoInstruction[] preallocate() { + GotoInstruction[] r = new GotoInstruction[256]; + for (int i = 0; i < r.length; i++) { + r[i] = new GotoInstruction(i); + } + return r; + } + + public static GotoInstruction make(int label) { + if (0 <= label && label < preallocated.length) { + return preallocated[label]; + } else { + return new GotoInstruction(label); + } + } + + public boolean isFallThrough() { + return false; + } + + public int[] getBranchTargets() { + return label; + } + + public int getLabel() { + return label[0]; + } + + public Instruction redirectTargets(int[] targetMap) { + return make(targetMap[label[0]]); + } + + public boolean equals(Object o) { + if (o instanceof GotoInstruction) { + GotoInstruction i = (GotoInstruction) o; + return i.label == label; + } else { + return false; + } + } + + public int hashCode() { + return label[0] * 1348091 + 18301; + } + + public String toString() { + return "Goto(" + getLabel() + ")"; + } + + public void visit(Visitor v) { + v.visitGoto(this); + } + /* (non-Javadoc) + * @see com.ibm.domo.cfg.IInstruction#isPEI() + */ + public boolean isPEI() { + return false; + } +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/IInstruction.java b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/IInstruction.java new file mode 100644 index 000000000..0845e61ce --- /dev/null +++ b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/IInstruction.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * 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.shrikeBT; + +/** + * @author sfink + * + * Basic functionality we expect of any instruction implementation + */ +public interface IInstruction { + + /** + * PEI == "Potentially excepting instruction" + * @return true iff this instruction might throw an exception + */ + boolean isPEI(); + +} diff --git a/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/IInvokeInstruction.java b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/IInvokeInstruction.java new file mode 100644 index 000000000..6638c591b --- /dev/null +++ b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/IInvokeInstruction.java @@ -0,0 +1,34 @@ +/******************************************************************************* + * 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.shrikeBT; + + +/** + * @author sfink + * + * Basic functionality any invoke instruction should provide + */ +public interface IInvokeInstruction extends IInstruction { + + + /** + * @return one of BytecodeConstants.INVOKE[SPECIAL|VIRTUAL|STATIC|INTERFACE] + */ + IDispatch getInvocationCode(); + + public interface IDispatch { + + } + + public static enum Dispatch implements IDispatch { + VIRTUAL, SPECIAL, STATIC, INTERFACE; + } +} diff --git a/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/InstanceofInstruction.java b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/InstanceofInstruction.java new file mode 100644 index 000000000..e4b19f18e --- /dev/null +++ b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/InstanceofInstruction.java @@ -0,0 +1,70 @@ +/******************************************************************************* + * 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.shrikeBT; + +/** + * This class represents instanceof instructions. + */ +public final class InstanceofInstruction extends Instruction { + private String type; + + protected InstanceofInstruction(String type) { + this.type = type; + this.opcode = OP_instanceof; + } + + public static InstanceofInstruction make(String type) { + return new InstanceofInstruction(type); + } + + public boolean equals(Object o) { + if (o instanceof InstanceofInstruction) { + InstanceofInstruction i = (InstanceofInstruction) o; + return i.type.equals(type); + } else { + return false; + } + } + + public int hashCode() { + return 31980190 + type.hashCode(); + } + + public int getPoppedCount() { + return 1; + } + + public String getType() { + return type; + } + + public String getPushedType(String[] types) { + return TYPE_boolean; + } + + public byte getPushedWordSize() { + return 1; + } + + public void visit(Visitor v) { + v.visitInstanceof(this); + } + + public String toString() { + return "Instanceof(" + type + ")"; + } + /* (non-Javadoc) + * @see com.ibm.domo.cfg.IInstruction#isPEI() + */ + public boolean isPEI() { + return false; + } +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/Instruction.java b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/Instruction.java new file mode 100644 index 000000000..7de9d8225 --- /dev/null +++ b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/Instruction.java @@ -0,0 +1,223 @@ +/******************************************************************************* + * 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.shrikeBT; + +/** + * Instructions are immutable objects. It is always legal to take a reference to + * an instruction and use it in any other context. You never need to copy + * instructions. It is often a good idea to keep references to frequently used + * instructions cached in static fields. + * + * To generate an Instruction, locate the class for the instruction you want to + * generate, and invoke the appropriate "make" static method on that class. The + * Util class has convenience methods for creating some of the more complex + * instructions using reflection to fill in some of the needed information + * (e.g., makeGet, makePut, makeInvoke). + * + * We simplify the bytecode instruction set a bit using some preprocessing and + * postprocessing: + * + * There is no 'iinc' instruction. 'iinc' instructions are expanded to 'iload; + * bipush; iadd; istore' during decoding and reassembled during compilation. + * + * There are no 'jsr' or 'ret' instructions. Bytecode subroutines are expanded + * inline during decoding. + * + * There are no 'ifeq', 'ifne', 'ifgt', 'ifge', 'iflt', 'ifle' instructions. + * These instructions are expanded to 'bipush 0; if_icmp' during decoding and + * reassembled during compilation. + * + * There are no 'ifnull' or 'ifnonnull' instructions. These instructions are + * expanded to 'aconst_null; if_acmp' during decoding and reassembled during + * compilation. + * + * All Java values, including longs and doubles, occupy just one word on the + * stack. Places where the JVM assumes differently are fixed up during + * compilation. However, longs and double still take up two local variable slots + * (this usually doesn't matter to instrumentation). + * + * Control transfer instructions refer to target instructions using integers. + * These integers are usually indices into an array of instructions. + */ +public abstract class Instruction implements Constants, Cloneable, IInstruction { + private final static int[] noInstructions = new int[0]; + + /** + * Ensure that only this package can subclass Instruction. + */ + Instruction() { + } + + short opcode = -1; + + /** + * @return true if the instruction can "fall through" to the following + * instruction + */ + public boolean isFallThrough() { + return true; + } + + /** + * @return an array containing the labels this instruction can branch to (not + * including the following instruction if this instruction 'falls + * through') + */ + public int[] getBranchTargets() { + return noInstructions; + } + + /** + * @return an Instruction equivalent to this one but with any branch labels + * updated by looking them up in the targetMap array + */ + public Instruction redirectTargets(int[] targetMap) { + return this; + } + + /** + * @return the number of values this instruction pops off the working stack + */ + public int getPoppedCount() { + return 0; + } + + /** + * @return the opcode selected for this instruction, or -1 if we don't know it + * yet + */ + public final short getOpcode() { + return opcode; + } + + /** + * Computes the type of data pushed onto the stack, or null if none is pushed. + * + * @param poppedTypesToCheck + * the types of the data popped off the stack by this instruction; if + * poppedTypes is null, then we don't know the incoming stack types + * and the result of this method may be less accurate + */ + public String getPushedType(String[] poppedTypesToCheck) { + return null; + } + + /** + * @return the JVM word size of the value this instruction pushes onto the + * stack, or 0 if this instruction doesn't push anything onto the + * stack. + */ + public byte getPushedWordSize() { + return 0; + } + + /** + * Apply a Visitor to this instruction. We invoke the appropriate Visitor + * method according to the type of this instruction. + */ + public abstract void visit(Visitor v); + + /** + * Subclasses must implement toString. + */ + public abstract String toString(); + + /** + * We're immutable so there's no need to clone any Instruction object. + */ + final public Object clone() { + return this; + } + + /** + * This class is used by Instruction.visit to dispatch based on the + * instruction type. + */ + public static abstract class Visitor { + public void visitConstant(ConstantInstruction instruction) { + } + + public void visitGoto(GotoInstruction instruction) { + } + + public void visitLocalLoad(LoadInstruction instruction) { + } + + public void visitLocalStore(StoreInstruction instruction) { + } + + public void visitArrayLoad(ArrayLoadInstruction instruction) { + } + + public void visitArrayStore(ArrayStoreInstruction instruction) { + } + + public void visitPop(PopInstruction instruction) { + } + + public void visitDup(DupInstruction instruction) { + } + + public void visitSwap(SwapInstruction instruction) { + } + + public void visitBinaryOp(BinaryOpInstruction instruction) { + } + + public void visitUnaryOp(UnaryOpInstruction instruction) { + } + + public void visitShift(ShiftInstruction instruction) { + } + + public void visitConversion(ConversionInstruction instruction) { + } + + public void visitComparison(ComparisonInstruction instruction) { + } + + public void visitConditionalBranch(ConditionalBranchInstruction instruction) { + } + + public void visitSwitch(SwitchInstruction instruction) { + } + + public void visitReturn(ReturnInstruction instruction) { + } + + public void visitGet(GetInstruction instruction) { + } + + public void visitPut(PutInstruction instruction) { + } + + public void visitInvoke(InvokeInstruction instruction) { + } + + public void visitNew(NewInstruction instruction) { + } + + public void visitArrayLength(ArrayLengthInstruction instruction) { + } + + public void visitThrow(ThrowInstruction instruction) { + } + + public void visitMonitor(MonitorInstruction instruction) { + } + + public void visitCheckCast(CheckCastInstruction instruction) { + } + + public void visitInstanceof(InstanceofInstruction instruction) { + } + } +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/InvokeInstruction.java b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/InvokeInstruction.java new file mode 100644 index 000000000..bba249834 --- /dev/null +++ b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/InvokeInstruction.java @@ -0,0 +1,192 @@ +/******************************************************************************* + * 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.shrikeBT; + +/** + * This class represents method invocation instructions. + */ +public class InvokeInstruction extends Instruction implements IInvokeInstruction { + protected String type; + protected String classType; + protected String methodName; + + InvokeInstruction(short opcode, String type, String classType, String methodName) { + this.type = type; + this.classType = classType; + this.methodName = methodName; + this.opcode = opcode; + } + + public static InvokeInstruction make(String type, String className, String methodName, Dispatch mode) { + if (type == null) { + throw new NullPointerException("type must not be null"); + } + if (className == null) { + throw new NullPointerException("className must not be null"); + } + if (methodName == null) { + throw new NullPointerException("methodName must not be null"); + } + return new InvokeInstruction((short) (OP_invokevirtual + mode.ordinal()), type, className, methodName); + } + + ConstantPoolReader getLazyConstantPool() { + return null; + } + + final static class Lazy extends InvokeInstruction { + private ConstantPoolReader cp; + private int index; + + Lazy(short opcode, ConstantPoolReader cp, int index) { + super(opcode, null, null, null); + this.index = index; + this.cp = cp; + } + + ConstantPoolReader getLazyConstantPool() { + return cp; + } + + int getCPIndex() { + return index; + } + + public String getClassType() { + if (classType == null) { + classType = cp.getConstantPoolMemberClassType(index); + } + return classType; + } + + public String getMethodName() { + if (methodName == null) { + methodName = cp.getConstantPoolMemberName(index); + } + return methodName; + } + + public String getMethodSignature() { + if (type == null) { + type = cp.getConstantPoolMemberType(index); + } + return type; + } + } + + static InvokeInstruction make(ConstantPoolReader cp, int index, int mode) { + if (mode < OP_invokevirtual || mode > OP_invokeinterface) { + throw new IllegalArgumentException("Unknown mode: " + mode); + } + return new Lazy((short) mode, cp, index); + } + + final public boolean equals(Object o) { + if (o instanceof InvokeInstruction) { + InvokeInstruction i = (InvokeInstruction) o; + return i.getMethodSignature().equals(getMethodSignature()) && i.getClassType().equals(getClassType()) + && i.getMethodName().equals(getMethodName()) && i.opcode == opcode; + } else { + return false; + } + } + + public String getClassType() { + return classType; + } + + public String getMethodName() { + return methodName; + } + + public String getMethodSignature() { + return type; + } + + final public int getInvocationMode() { + return opcode; + } + + final public String getInvocationModeString() { + switch (opcode) { + case Constants.OP_invokestatic: + return "STATIC"; + case Constants.OP_invokeinterface: + return "INTERFACE"; + case Constants.OP_invokespecial: + return "SPECIAL"; + case Constants.OP_invokevirtual: + return "VIRTUAL"; + default: + throw new Error("Unknown mode: " + opcode); + } + } + + final public int hashCode() { + return getMethodSignature().hashCode() + 9011 * getClassType().hashCode() + 317 * getMethodName().hashCode() + opcode * 3188; + } + + final public int getPoppedCount() { + return (opcode == Constants.OP_invokestatic ? 0 : 1) + Util.getParamsCount(getMethodSignature()); + } + + final public String getPushedType(String[] types) { + String t = Util.getReturnType(getMethodSignature()); + if (t.equals(Constants.TYPE_void)) { + return null; + } else { + return t; + } + } + + final public byte getPushedWordSize() { + String t = getMethodSignature(); + int index = t.lastIndexOf(')'); + return Util.getWordSize(t, index + 1); + } + + final public void visit(Visitor v) { + v.visitInvoke(this); + } + + final public String toString() { + return "Invoke(" + getInvocationModeString() + "," + getClassType() + "," + getMethodName() + "," + getMethodSignature() + ")"; + } + + /* + * (non-Javadoc) + * + * @see com.ibm.domo.cfg.IInstruction#isPEI() + */ + public boolean isPEI() { + return true; + } + + /* + * (non-Javadoc) + * + * @see com.ibm.domo.cfg.IInvokeInstruction#getInvocationCode() + */ + public Dispatch getInvocationCode() { + switch (opcode) { + case Constants.OP_invokestatic: + return Dispatch.STATIC; + case Constants.OP_invokeinterface: + return Dispatch.INTERFACE; + case Constants.OP_invokespecial: + return Dispatch.SPECIAL; + case Constants.OP_invokevirtual: + return Dispatch.VIRTUAL; + default: + throw new Error("Unknown mode: " + opcode); + } + } +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/LoadInstruction.java b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/LoadInstruction.java new file mode 100644 index 000000000..44a2b16aa --- /dev/null +++ b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/LoadInstruction.java @@ -0,0 +1,100 @@ +/******************************************************************************* + * 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.shrikeBT; + +/** + * This class represents local variable load instructions. + */ +public final class LoadInstruction extends Instruction { + private int index; + + protected LoadInstruction(short opcode, int index) { + this.index = index; + this.opcode = opcode; + } + + private final static LoadInstruction[] preallocated = preallocate(); + + private static LoadInstruction[] preallocate() { + LoadInstruction[] r = new LoadInstruction[5 * 16]; + for (int p = 0; p < 5; p++) { + for (int i = 0; i < 4; i++) { + r[p * 16 + i] = new LoadInstruction((short) (OP_iload_0 + i + p * 4), i); + } + for (int i = 4; i < 16; i++) { + r[p * 16 + i] = new LoadInstruction((short) (OP_iload + p), i); + } + } + return r; + } + + public static LoadInstruction make(String type, int index) { + int t = Util.getTypeIndex(type); + if (t < 0 || t > TYPE_Object_index) { + throw new IllegalArgumentException("Cannot load local of type " + type); + } + if (index < 16) { + return preallocated[t * 16 + index]; + } else { + return new LoadInstruction((short) (OP_iload + t), index); + } + } + + /** + * @return the index of the local variable loaded + */ + public int getVarIndex() { + return index; + } + + public String getType() { + if (opcode < OP_iload_0) { + return indexedTypes[opcode - OP_iload]; + } else { + return indexedTypes[(opcode - OP_iload_0) / 4]; + } + } + + public String getPushedType(String[] types) { + return getType(); + } + + public byte getPushedWordSize() { + return Util.getWordSize(getType()); + } + + public void visit(Visitor v) { + v.visitLocalLoad(this); + } + + public boolean equals(Object o) { + if (o instanceof LoadInstruction) { + LoadInstruction i = (LoadInstruction) o; + return i.index == index && i.opcode == opcode; + } else { + return false; + } + } + + public int hashCode() { + return opcode + index * 19801901; + } + + public String toString() { + return "LocalLoad(" + getType() + "," + index + ")"; + } + /* (non-Javadoc) + * @see com.ibm.domo.cfg.IInstruction#isPEI() + */ + public boolean isPEI() { + return false; + } +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/MethodData.java b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/MethodData.java new file mode 100644 index 000000000..e51fa128c --- /dev/null +++ b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/MethodData.java @@ -0,0 +1,243 @@ +/******************************************************************************* + * 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.shrikeBT; + +import java.util.HashMap; +import java.util.Iterator; + +/** + * This class is a container for a bunch of information that we might know about + * a method. It's here for convenience so users can just pass one MethodData + * around instead of passing around an array of instructions, an array of + * exception handler lists, etc. + * + * It also provides a place to hang annotations. We provide a table mapping + * abstract "keys" to annotation objects. We also provide an invalidation + * protocol so that the annotation objects can be notified of code changes and + * react appropriately. This is useful for caching analysis results for a + * method. + */ +public final class MethodData { + private HashMap map = new HashMap(); + + private int access; + private String classType; + private String name; + private String signature; + private Instruction[] instructions; + private ExceptionHandler[][] handlers; + private int[] instructionsToBytecodes; + private boolean hasChanged = false; + + /** + * Gather the information for a method "from scratch". + * + * @param access + * the access flags + * @param classType + * the class in which the method is defined, in JVM type format + * (e.g., Ljava/lang/Object;) + * @param name + * the method name + * @param signature + * the method signature, in JVM type format (e.g., + * (ILjava/lang/Object;)V) + * @param instructions + * the instructions making up the method + * @param handlers + * a list of exception handlers for each instruction + * @param instructionsToBytecodes + * a map stating, for each instruction, the offset of the original + * bytecode instruction(s) giving rise to this instruction + */ + public MethodData(int access, String classType, String name, String signature, Instruction[] instructions, + ExceptionHandler[][] handlers, int[] instructionsToBytecodes) { + this.classType = classType; + this.access = access; + this.name = name; + this.signature = signature; + this.instructions = instructions; + this.handlers = handlers; + this.instructionsToBytecodes = instructionsToBytecodes; + + if (instructions == null) { + throw new NullPointerException("Instruction array cannot be null"); + } + if (handlers == null) { + throw new NullPointerException("Handler array cannot be null"); + } + if (instructionsToBytecodes == null) { + throw new NullPointerException("InstructionToBytecodes array cannot be null"); + } + if (instructions.length != handlers.length) { + throw new IllegalArgumentException("Handlers array must be the same length as the instructions"); + } + if (instructions.length != instructionsToBytecodes.length) { + throw new IllegalArgumentException("Bytecode map array must be the same length as the instructions"); + } + } + + /** + * Gather the information for a method after it has been decoded. + * + * @param d + * the decoder which has decoded the method + * @param access + * the access flags + * @param classType + * the class in which the method is defined, in JVM type format + * (e.g., Ljava/lang/Object;) + * @param name + * the method name + * @param signature + * the method signature, in JVM type format (e.g., + * (ILjava/lang/Object;)V) + */ + public MethodData(Decoder d, int access, String classType, String name, String signature) { + this(access, classType, name, signature, d.getInstructions(), d.getHandlers(), d.getInstructionsToBytecodes()); + } + + public void setHasChanged() { + hasChanged = true; + } + + /** + * @return the method signature, in JVM format + */ + public String getSignature() { + return signature; + } + + /** + * @return the method name + */ + public String getName() { + return name; + } + + /** + * Xiangyu, + * + * @return the method access + */ + public int getAccess() { + return access; + } + + /** + * @return the JVM type for the class defining the method (e.g., + * Ljava/lang/Object;) + */ + public String getClassType() { + return classType; + } + + /** + * @return whether or not the method is static + */ + public boolean getIsStatic() { + return (access & Constants.ACC_STATIC) != 0; + } + + /** + * @return whether or not the method is synchronized + */ + public boolean getIsSynchronized() { + return (access & Constants.ACC_SYNCHRONIZED) != 0; + } + + /** + * @return the exception handler lists + */ + public ExceptionHandler[][] getHandlers() { + return handlers; + } + + /** + * @return the instruction array + */ + public Instruction[] getInstructions() { + return instructions; + } + + /** + * @return the map from instructions to bytecode offsets + */ + public int[] getInstructionsToBytecodes() { + return instructionsToBytecodes; + } + + /** + * Annotation objects implement this Results interface. The Results interface + * is used to notify an annotation that the method code has been updated. + */ + public static interface Results { + /** + * This method is called just before the code for a method changes. The + * existing instructions, handlers, etc can be read from the current info. + * + * @param info + * the method data this annotation is attached to + * @param newInstructions + * the instructions the method will change to + * @param newHandlers + * the handler lists the method will change to + * @param newInstructionMap + * the instructions-to-bytecodes map the method will change to + * @return true to remove the object from the info set, for example because + * the annotation is now invalid + */ + public boolean notifyUpdate(MethodData info, Instruction[] newInstructions, ExceptionHandler[][] newHandlers, + int[] newInstructionMap); + } + + /** + * Get the annotation for the given key. + * + * @return the annotation or null if there isn't one + */ + public Results getInfo(Object key) { + return map.get(key); + } + + /** + * Set the annotation for the given key. + */ + public void putInfo(Object key, Results value) { + map.put(key, value); + } + + void update(Instruction[] instructions, ExceptionHandler[][] handlers, int[] newInstructionMap, int[] instructionsToBytecodes) { + for (Iterator i = map.keySet().iterator(); i.hasNext();) { + Object key = i.next(); + Results r = map.get(key); + if (r.notifyUpdate(this, instructions, handlers, newInstructionMap)) { + i.remove(); + } + } + + this.instructions = instructions; + this.handlers = handlers; + this.instructionsToBytecodes = instructionsToBytecodes; + hasChanged = true; + } + + /** + * @return true iff the code has been updated at least once + */ + public boolean getHasChanged() { + return hasChanged; + } + + public String toString() { + return getClassType() + "." + getName() + getSignature(); + } +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/MethodEditor.java b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/MethodEditor.java new file mode 100644 index 000000000..b40924c2f --- /dev/null +++ b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/MethodEditor.java @@ -0,0 +1,707 @@ +/******************************************************************************* + * 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.shrikeBT; + +import java.util.ArrayList; +import java.util.HashSet; + +/** + * The MethodEditor is the core of the ShrikeBT code rewriting mechanism. To + * rewrite code, construct a MethodEditor initialized with the intial code for + * the method. Then perform a series of passes. In each pass you call + * beginPass(), insert a number of patches using the insert...() or replace...() + * methods, then optionally call applyPatches() to update the code with your + * changes, then call endPass(). The end of each pass updates the code in the + * MethodData that you passed in, so the new code can be extracted from that + * MethodData object. Note that if applyPatches() is not called, or it is called + * but no patches had been inserted, then the code will not be updated and that + * pass is essentially aborted. + * + * A patch is simply a subclass of MethodEditor.Patch, representing a code + * sequence to insert into the method. Each patch class implements one method, + * emitTo(), which writes the patch code into the code stream using the provided + * MethodEditor.Output instance. Anonymous inner classes are very useful for + * writing patches. + * + * Patches can be inserted at the following points: + *
                                + *
                              • Before the start of the method + *
                              • Before or after a particular instruction + *
                              • Replacing a particular instruction + *
                              • Handling an exception on a particular instruction + *
                              • Handling an exception anywhere in the method + *
                              • After the end of the method, where code will not normally be executed, + * but can be branched to by another patch + *
                              + * Patch application is deterministic; if two patches are applied at the same + * point, then the order of application determines the order of code generation, + * in a way specified by the particular application point. See the patch + * application methods below. + * + * MethodEditor relies on labels. A label is an integer representing a point in + * the code. Labels are valid only during a single pass; at the end of each + * pass, instructions are reordered and old labels become invalid. At the + * beginning of a pass every instruction in the instructions array is labelled + * with the index of that instruction in the array. During instrumentation new + * labels can be allocated by calling MethodEditor.allocateLabel(); control + * instructions can be created referring to these new labels or the existing + * labels. At the end of a pass, as patch code is spliced into the method body, + * all instructions are updated to refer to the new labels which are simply the + * indices of instructions in the instruction array. + */ +public final class MethodEditor { + private static final ExceptionHandler[] noHandlers = new ExceptionHandler[0]; + + /** Records which original bytecode instruction each Instruction belongs to. */ + private int[] instructionsToBytecodes; + private Instruction[] instructions; + private ExceptionHandler[][] handlers; + + private MethodData methodInfo; + + // working + private static final int BEFORE_PASS = 0x01; + private static final int DURING_PASS = 0x02; + private static final int EMITTING_CODE = 0x04; + private static final int BEFORE_END_PASS = 0x08; + + private int state = BEFORE_PASS; + private int patchCount; + private Patch[] beforePatches; + private Patch[] afterPatches; + private Patch[] lastAfterPatches; + private Patch[] replacementPatches; + private Patch methodStartPatches; + private Patch afterMethodPatches; + private HandlerPatch[] instructionHandlerPatches; + private HandlerPatch methodHandlerPatches; + private int nextLabel; + + /** + * This patch lets us stuff an exception handler into the code. + */ + private static class HandlerPatch { + HandlerPatch next; + String catchClass; + int label; + Patch patch; + + HandlerPatch(HandlerPatch next, String catchClass, int label, Patch patch) { + this.next = next; + this.catchClass = catchClass; + this.label = label; + this.patch = patch; + } + } + + /** + * Build an editor for the given method. This editor will write back its + * changes to the method info. + */ + public MethodEditor(MethodData info) { + methodInfo = info; + instructionsToBytecodes = info.getInstructionsToBytecodes(); + instructions = info.getInstructions(); + handlers = info.getHandlers(); + } + + /** + * Build an editor for specific method data. After patching the code you can + * retrieve the new code, handlers and instructions-to-bytecode-offsets map. + */ + public MethodEditor(Instruction[] instructions, ExceptionHandler[][] handlers, int[] instructionsToBytecodes) { + methodInfo = null; + this.instructionsToBytecodes = instructionsToBytecodes; + this.instructions = instructions; + this.handlers = handlers; + } + + private void verifyState(int state) { + if ((state & this.state) == 0) { + throw new IllegalArgumentException(getStateMessage(state)); + } + } + + private String getStateMessage(int state) { + switch (state) { + case BEFORE_PASS: + return "This operation can only be performed before or after an editing pass"; + case DURING_PASS: + return "This operation can only be performed during an editing pass"; + case EMITTING_CODE: + return "This operation can only be performed while applying patches and emitting code"; + case BEFORE_END_PASS: + return "This operation can only be performed after applying patches"; + default: + return "This operation cannot be performed in this state"; + } + } + + /** + * @return the current handler array + */ + public ExceptionHandler[][] getHandlers() { + verifyState(BEFORE_PASS | DURING_PASS); + return handlers; + } + + /** + * @return the current instruction array + */ + public Instruction[] getInstructions() { + verifyState(BEFORE_PASS | DURING_PASS); + return instructions; + } + + /** + * @return the current instructions-to-bytecode-offsets map + */ + public int[] getInstructionsToBytecodes() { + verifyState(BEFORE_PASS | DURING_PASS); + return instructionsToBytecodes; + } + + static ExceptionHandler[] mergeHandlers(ExceptionHandler[] h1, ExceptionHandler[] h2) { + if (h1.length == 0) { + return h2; + } else if (h2.length == 0) { + return h1; + } else { + ExceptionHandler[] r = new ExceptionHandler[h1.length + h2.length]; + System.arraycopy(h1, 0, r, 0, h1.length); + System.arraycopy(h2, 0, r, h1.length, h2.length); + return r; + } + } + + /** + * Output is the interface that patches use to emit their code into a method + * body. + */ + public final static class Output { + ArrayList newInstructions = new ArrayList(); + ArrayList newInstructionHandlers = new ArrayList(); + int[] instructionsToBytecodes = new int[10]; + int[] labelDefs; + ExceptionHandler[] additionalHandlers; + int originalBytecode; + boolean codeChanged = false; + + Output(int numLabels) { + labelDefs = new int[numLabels]; + } + + /** + * Emit a label definition at the current point in the code. The label must + * have been previously allocated using MethodEditor.allocateLabel. + */ + public void emitLabel(int label) { + labelDefs[label] = newInstructions.size(); + } + + /** + * Emit an instruction at the current point in the code. + */ + public void emit(Instruction i) { + codeChanged = true; + internalEmitInstruction(i); + } + + /** + * Emit an instruction with some exception handlers at the current point in + * the code. + */ + public void emit(Instruction i, ExceptionHandler[] handlers) { + codeChanged = true; + + int s = newInstructions.size(); + if (s + 1 > instructionsToBytecodes.length) { + int[] t = new int[instructionsToBytecodes.length * 2]; + System.arraycopy(instructionsToBytecodes, 0, t, 0, instructionsToBytecodes.length); + instructionsToBytecodes = t; + } + + instructionsToBytecodes[s] = originalBytecode; + newInstructions.add(i); + newInstructionHandlers.add(mergeHandlers(handlers, additionalHandlers)); + } + + void internalEmitInstruction(Instruction i) { + int s = newInstructions.size(); + if (s + 1 > instructionsToBytecodes.length) { + int[] t = new int[instructionsToBytecodes.length * 2]; + System.arraycopy(instructionsToBytecodes, 0, t, 0, instructionsToBytecodes.length); + instructionsToBytecodes = t; + } + + instructionsToBytecodes[s] = originalBytecode; + newInstructions.add(i); + newInstructionHandlers.add(additionalHandlers); + } + + /** + * Emit a list of instructions at the current point in the code. + */ + public void emit(Instruction[] instrs) { + emit(instrs, noHandlers); + } + + /** + * Emit a list of instructions with some exception handlers at the current + * point in the code. All the instructions are covered by all the handlers. + */ + public void emit(Instruction[] instrs, ExceptionHandler[] handlers) { + if (instrs.length == 0) { + return; + } + codeChanged = true; + + int s = newInstructions.size(); + if (s + instrs.length > instructionsToBytecodes.length) { + int[] t = new int[instructionsToBytecodes.length * 2 + instrs.length]; + System.arraycopy(instructionsToBytecodes, 0, t, 0, instructionsToBytecodes.length); + instructionsToBytecodes = t; + } + + ExceptionHandler[] hs = mergeHandlers(handlers, additionalHandlers); + for (int i = 0; i < instrs.length; i++) { + instructionsToBytecodes[s + i] = originalBytecode; + newInstructions.add(instrs[i]); + newInstructionHandlers.add(hs); + } + } + } + + /** + * This class is subclassed for each kind of patch that you want to apply. + */ + public static abstract class Patch { + Patch next; + + public Patch() { + } + + final Patch insert(Patch next) { + this.next = next; + return this; + } + + /** + * Override this method to emit the code for your patch. + */ + public abstract void emitTo(Output w); + } + + /** + * This must be called before inserting any patches. + */ + public void beginPass() { + verifyState(BEFORE_PASS); + state = DURING_PASS; + + nextLabel = instructions.length; + beforePatches = new Patch[instructions.length]; + afterPatches = new Patch[instructions.length]; + lastAfterPatches = new Patch[instructions.length]; + replacementPatches = new Patch[instructions.length]; + instructionHandlerPatches = new HandlerPatch[instructions.length]; + methodStartPatches = null; + afterMethodPatches = null; + methodHandlerPatches = null; + patchCount = 0; + } + + /** + * This must be called after inserting any patches. + */ + public void endPass() { + state = BEFORE_PASS; + + // lose references to the stored patches so they can be garbage collected + beforePatches = null; + afterPatches = null; + lastAfterPatches = null; + replacementPatches = null; + instructionHandlerPatches = null; + methodStartPatches = null; + afterMethodPatches = null; + methodHandlerPatches = null; + } + + /** + * Allocate a fresh label. This must be called during a pass and not during + * code emission. + */ + public int allocateLabel() { + verifyState(DURING_PASS); + return nextLabel++; + } + + /** + * Insert code to be executed whenever the method is entered. This code is not + * protected by any exception handlers (other than handlers declared in the + * patch). + * + * When multiple 'start' patches are given, the last one added is first in + * execution order. + */ + public void insertAtStart(Patch p) { + verifyState(DURING_PASS); + methodStartPatches = p.insert(methodStartPatches); + patchCount++; + } + + /** + * Insert code to be executed before the instruction. Branches to the + * instruction will branch to this code. Exception handlers that cover the + * instruction will be extended to cover the patch. + * + * When multiple 'before' patches are given, the last one added is first in + * execution order. + */ + public void insertBefore(int i, Patch p) { + verifyState(DURING_PASS); + beforePatches[i] = p.insert(beforePatches[i]); + patchCount++; + } + + /** + * Insert code to be executed after the instruction. This code will only + * execute if the instruction "falls through". For example, code inserted + * after a "goto" will never be executed. Likewise if the instruction throws + * an execution the 'after' code will not be executed. Exception handlers that + * cover the instruction will be extended to cover the patch. + * + * When multiple 'after' patches are given, the last one added is LAST in + * execution order. + */ + public void insertAfter(int i, Patch p) { + verifyState(DURING_PASS); + if (afterPatches[i] == null) { + lastAfterPatches[i] = afterPatches[i] = p.insert(null); + } else { + lastAfterPatches[i].next = p; + lastAfterPatches[i] = p.insert(null); + } + patchCount++; + } + + /** + * Insert code to replace the instruction. Exception handlers that cover the + * instruction will cover the patch. + * + * Multiple replacements are not allowed. + */ + public void replaceWith(int i, Patch p) { + verifyState(DURING_PASS); + if (replacementPatches[i] != null) { + throw new IllegalArgumentException("Instruction " + i + " cannot be replaced more than once"); + } + replacementPatches[i] = p.insert(null); + patchCount++; + } + + /** + * An "instruction exception handler" handles exceptions generated by a + * specific instruction (including patch code that may be inserted before, + * after, or instead of the instruction in this pass). If the patch code falls + * through, control resumes with the next instruction. This exception handler + * handles exceptions before any exception handler already attached to the + * instruction. Furthermore, the patch itself is covered by the exception + * handlers already attached to the instruction. + * + * If multiple instruction exception handlers are given, then the last one + * added handles the exception first; if an exception is rethrown, then the + * next-to-last one added handles that exception, etc. + */ + public void addInstructionExceptionHandler(int i, String catchClass, Patch p) { + verifyState(DURING_PASS); + instructionHandlerPatches[i] = new HandlerPatch(instructionHandlerPatches[i], catchClass, allocateLabel(), p); + patchCount++; + } + + /** + * A "method exception handler" handles exceptions generated anywhere in the + * method. The patch code must not fall through; it must return or throw an + * exception. + * + * If multiple method exception handlers are given, then the last one added + * handles the exception first; if an exception is rethrown, then the + * next-to-last one added handles that exception, etc. + */ + public void addMethodExceptionHandler(String catchClass, Patch p) { + verifyState(DURING_PASS); + methodHandlerPatches = new HandlerPatch(methodHandlerPatches, catchClass, allocateLabel(), p); + patchCount++; + } + + /** + * This method inserts code that will be placed after the method body. This + * code will not be executed normally, but it can emit label definitions that + * other patches can branch to. No exception handlers cover this code (other + * than exception handlers emitted by patch p itself). + */ + public void insertAfterBody(Patch p) { + verifyState(DURING_PASS); + afterMethodPatches = p.insert(afterMethodPatches); + patchCount++; + } + + /** + * @return the MethodData used to create this editor, or null if no MethodData + * is linked to this editor + */ + public MethodData getData() { + return methodInfo; + } + + private static ExceptionHandler[] makeExceptionArray(HandlerPatch hp) { + if (hp == null) { + return noHandlers; + } else { + int count = 0; + for (HandlerPatch hpIterator = hp; hpIterator != null; hpIterator = hpIterator.next) { + count++; + } + + ExceptionHandler[] patchedHandlers = new ExceptionHandler[count]; + count = 0; + for (HandlerPatch hpIterator = hp; hpIterator != null; hpIterator = hpIterator.next) { + patchedHandlers[count] = new ExceptionHandler(hpIterator.label, hpIterator.catchClass); + count++; + } + + return patchedHandlers; + } + } + + /** + * This method finishes a pass. All code is updated; instructions are + * reordered and old labels may not be valid. + * + * If no patches were issued, we don't need to do anything at all; this case + * is detected quickly and no updates are made. + * + * @return true iff non-trivial patches were applied + */ + public boolean applyPatches() { + verifyState(DURING_PASS); + state = EMITTING_CODE; + + if (patchCount == 0) { + state = BEFORE_END_PASS; + // no patches issued; drop out + return false; + } + + Output w = new Output(nextLabel); + + int[] oldInstructionsToNew = new int[instructions.length]; + + w.additionalHandlers = noHandlers; + w.originalBytecode = 0; + for (Patch p = methodStartPatches; p != null; p = p.next) { + p.emitTo(w); + } + + ExceptionHandler[] methodHandlers = makeExceptionArray(methodHandlerPatches); + if (methodHandlers.length > 0) { + // if a method handler is added, the code has changed even though + // the patch might not emit any actual code + w.codeChanged = true; + } + + for (int i = 0; i < instructions.length; i++) { + ExceptionHandler[] basicHandlers = mergeHandlers(handlers[i], methodHandlers); + HandlerPatch hp = instructionHandlerPatches[i]; + + w.emitLabel(i); + w.originalBytecode = instructionsToBytecodes[i]; + + w.additionalHandlers = basicHandlers; + for (Patch p = beforePatches[i]; p != null; p = p.next) { + p.emitTo(w); + } + + w.additionalHandlers = mergeHandlers(makeExceptionArray(hp), basicHandlers); + Patch replace = replacementPatches[i]; + if (replace == null) { + oldInstructionsToNew[i] = w.newInstructions.size(); + w.internalEmitInstruction(instructions[i]); + } else { + // a patch might delete an instruction, in which case the + // code is definitely modified + w.codeChanged = true; + oldInstructionsToNew[i] = -1; + replace.emitTo(w); + } + + w.additionalHandlers = basicHandlers; + for (Patch p = afterPatches[i]; p != null; p = p.next) { + p.emitTo(w); + } + + if (hp != null) { + // if an instruction handler is added, the code has changed even though + // the patch might not emit any actual code + w.codeChanged = true; + + GotoInstruction branchOver = GotoInstruction.make(i + 1); + + w.internalEmitInstruction(branchOver); + for (HandlerPatch hpIterator = hp; hpIterator != null; hpIterator = hpIterator.next) { + w.additionalHandlers = mergeHandlers(makeExceptionArray(hpIterator.next), basicHandlers); + w.emitLabel(hpIterator.label); + hpIterator.patch.emitTo(w); + w.internalEmitInstruction(branchOver); + } + } + } + + w.originalBytecode = 0; + + for (HandlerPatch hpIterator = methodHandlerPatches; hpIterator != null; hpIterator = hpIterator.next) { + w.additionalHandlers = makeExceptionArray(hpIterator.next); + w.emitLabel(hpIterator.label); + hpIterator.patch.emitTo(w); + } + + w.additionalHandlers = noHandlers; + for (Patch p = afterMethodPatches; p != null; p = p.next) { + p.emitTo(w); + } + + state = BEFORE_END_PASS; + + if (!w.codeChanged) { + return false; + } + + instructions = new Instruction[w.newInstructions.size()]; + handlers = new ExceptionHandler[instructions.length][]; + instructionsToBytecodes = new int[instructions.length]; + + w.newInstructions.toArray(instructions); + w.newInstructionHandlers.toArray(handlers); + System.arraycopy(w.instructionsToBytecodes, 0, instructionsToBytecodes, 0, instructionsToBytecodes.length); + + int[] labelDefs = w.labelDefs; + + int[] newInstructionsToOld = new int[instructions.length]; + + for (int i = 0; i < instructions.length; i++) { + instructions[i] = instructions[i].redirectTargets(labelDefs); + newInstructionsToOld[i] = -1; + } + + // We want to update each exception handler array exactly once + HashSet adjustedHandlers = null; + for (int i = 0; i < handlers.length; i++) { + ExceptionHandler[] hs = handlers[i]; + if (hs.length > 0 && (i == 0 || hs != handlers[i - 1])) { + if (adjustedHandlers == null) { + adjustedHandlers = new HashSet(); + } + + for (int j = 0; j < hs.length; j++) { + ExceptionHandler h = hs[j]; + if (!adjustedHandlers.contains(h)) { + adjustedHandlers.add(h); + h.handler = labelDefs[h.handler]; + } + } + } + } + + if (methodInfo != null) { + for (int i = 0; i < oldInstructionsToNew.length; i++) { + if (oldInstructionsToNew[i] != -1) { + newInstructionsToOld[oldInstructionsToNew[i]] = i; + } + } + methodInfo.update(instructions, handlers, newInstructionsToOld, instructionsToBytecodes); + } + + return true; + } + + /** + * Apply Visitor v to each instruction in the code, for the purpose of + * patching the code. + */ + public void visitInstructions(Visitor v) { + verifyState(DURING_PASS); + + for (int i = 0; i < instructions.length; i++) { + v.setIndex(this, i); + instructions[i].visit(v); + } + } + + /** + * A specialized Instruction.Visitor providing convenience methods for + * inserting patches. In particular it maintains a notion of the "current + * position" in the code array. + */ + public static class Visitor extends Instruction.Visitor { + private int index; + private MethodEditor editor; + + /** + * Set the current editor and instruction index for this visitor. + */ + final public void setIndex(MethodEditor e, int i) { + index = i; + editor = e; + } + + /** + * @return the index of the current instruction in the code array + */ + final public int getIndex() { + return index; + } + + /** + * Insert a patch after the current instruction in the code. + */ + final public void insertAfter(Patch p) { + editor.insertAfter(index, p); + } + + /** + * Insert a patch before the current instruction in the code. + */ + final public void insertBefore(Patch p) { + editor.insertBefore(index, p); + } + + /** + * Replace the current instruction in the code with a patch. + */ + final public void replaceWith(Patch p) { + editor.replaceWith(index, p); + } + + /** + * Add an exception handler to the current instruction. + * + * @param catchClass + * the JVM type for the exception to be caught (e.g., + * Ljava.io.IOException;), or null to catch all exceptions + * @param p + * the code to handle the exception + */ + final public void addInstructionExceptionHandler(String catchClass, Patch p) { + editor.addInstructionExceptionHandler(index, catchClass, p); + } + } +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/MonitorInstruction.java b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/MonitorInstruction.java new file mode 100644 index 000000000..a6b1e0a06 --- /dev/null +++ b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/MonitorInstruction.java @@ -0,0 +1,62 @@ +/******************************************************************************* + * 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.shrikeBT; + +/** + * This class represents monitorenter and monitorexit instructions. + */ +public final class MonitorInstruction extends Instruction { + protected MonitorInstruction(short opcode) { + this.opcode = opcode; + } + + private final static MonitorInstruction enter = new MonitorInstruction(OP_monitorenter); + private final static MonitorInstruction exit = new MonitorInstruction(OP_monitorexit); + + public static MonitorInstruction make(boolean entering) { + return entering ? enter : exit; + } + + public boolean equals(Object o) { + if (o instanceof MonitorInstruction) { + MonitorInstruction i = (MonitorInstruction) o; + return i.opcode == opcode; + } else { + return false; + } + } + + public boolean isEnter() { + return opcode == OP_monitorenter; + } + + public int hashCode() { + return opcode + 1911; + } + + public int getPoppedCount() { + return 1; + } + + public void visit(Visitor v) { + v.visitMonitor(this); + } + + public String toString() { + return "Monitor(" + (isEnter() ? "ENTER" : "EXIT") + ")"; + } + /* (non-Javadoc) + * @see com.ibm.domo.cfg.IInstruction#isPEI() + */ + public boolean isPEI() { + return true; + } +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/NewInstruction.java b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/NewInstruction.java new file mode 100644 index 000000000..e94c5d482 --- /dev/null +++ b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/NewInstruction.java @@ -0,0 +1,109 @@ +/******************************************************************************* + * 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.shrikeBT; + +public final class NewInstruction extends Instruction { + private String type; + private short arrayBoundsCount; + + protected NewInstruction(short opcode, String type, short arrayBoundsCount) { + this.type = type; + this.arrayBoundsCount = arrayBoundsCount; + this.opcode = opcode; + } + + /** + * @param type + * the type of the object that will be returned (in JVM format, e.g., + * [Ljava/lang/String;) + * @param arrayBoundsCount + * the number of array dimensions to preconstruct (equal to the + * number of integer parameters this instruction expects) + */ + public static NewInstruction make(String type, int arrayBoundsCount) { + if (arrayBoundsCount < 0 || arrayBoundsCount > 255) { + throw new IllegalArgumentException("Too many array bounds: " + arrayBoundsCount); + } else { + if (type.length() < arrayBoundsCount + 1) { + throw new IllegalArgumentException("Not enough array nesting in " + type + " for bounds count " + arrayBoundsCount); + } + for (int i = 0; i < arrayBoundsCount; i++) { + if (type.charAt(i) != '[') { + throw new IllegalArgumentException("Not enough array nesting in " + type + " for bounds count " + arrayBoundsCount); + } + } + + short opcode; + + if (arrayBoundsCount == 0) { + opcode = OP_new; + } else if (arrayBoundsCount == 1) { + char ch = type.charAt(1); + if (ch != 'L' && ch != '[') { + // array of primitive type + opcode = OP_newarray; + } else { + opcode = OP_anewarray; + } + } else { + opcode = OP_multianewarray; + } + return new NewInstruction(opcode, type, (short) arrayBoundsCount); + } + } + + public boolean equals(Object o) { + if (o instanceof NewInstruction) { + NewInstruction i = (NewInstruction) o; + return i.type.equals(type) && i.arrayBoundsCount == arrayBoundsCount; + } else { + return false; + } + } + + public int getArrayBoundsCount() { + return arrayBoundsCount; + } + + public int hashCode() { + return 13111143 * type.hashCode() + arrayBoundsCount; + } + + public int getPoppedCount() { + return arrayBoundsCount; + } + + public String getPushedType(String[] types) { + return type; + } + + public byte getPushedWordSize() { + return 1; + } + + public String getType() { + return type; + } + + public String toString() { + return "New(" + type + "," + arrayBoundsCount + ")"; + } + + public void visit(Visitor v) { + v.visitNew(this); + } + /* (non-Javadoc) + * @see com.ibm.domo.cfg.IInstruction#isPEI() + */ + public boolean isPEI() { + return true; + } +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/PopInstruction.java b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/PopInstruction.java new file mode 100644 index 000000000..18b4e1aea --- /dev/null +++ b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/PopInstruction.java @@ -0,0 +1,65 @@ +/******************************************************************************* + * 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.shrikeBT; + +/** + * PopInstructions pop one or two elements off the working stack. + */ +public final class PopInstruction extends Instruction { + private byte size; + + protected PopInstruction(byte size) { + this.size = size; + } + + /** + * @param size + * 1 or 2, the number of elements to pop + */ + public static PopInstruction make(int size) { + if (size < 0 || size > 2) { + throw new IllegalArgumentException("Invalid pop size: " + size); + } else { + return new PopInstruction((byte) size); + } + } + + public boolean equals(Object o) { + if (o instanceof PopInstruction) { + PopInstruction i = (PopInstruction) o; + return i.size == size; + } else { + return false; + } + } + + public int hashCode() { + return size + 8431890; + } + + public int getPoppedCount() { + return size; + } + + public void visit(Visitor v) { + v.visitPop(this); + } + + public String toString() { + return "Pop(" + size + ")"; + } + /* (non-Javadoc) + * @see com.ibm.domo.cfg.IInstruction#isPEI() + */ + public boolean isPEI() { + return false; + } +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/PutInstruction.java b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/PutInstruction.java new file mode 100644 index 000000000..ce3ffab1a --- /dev/null +++ b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/PutInstruction.java @@ -0,0 +1,137 @@ +/******************************************************************************* + * 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.shrikeBT; + +/** + * This class represents put and putstatic instructions. + */ +public class PutInstruction extends Instruction { + protected String type; + protected String classType; + protected String fieldName; + + PutInstruction(short opcode, String type, String classType, String fieldName) { + this.type = type; + this.classType = classType; + this.fieldName = fieldName; + this.opcode = opcode; + } + + ConstantPoolReader getLazyConstantPool() { + return null; + } + + final static class Lazy extends PutInstruction { + private ConstantPoolReader cp; + private int index; + + Lazy(short opcode, ConstantPoolReader cp, int index) { + super(opcode, null, null, null); + this.index = index; + this.cp = cp; + } + + ConstantPoolReader getLazyConstantPool() { + return cp; + } + + int getCPIndex() { + return index; + } + + public String getClassType() { + if (classType == null) { + classType = cp.getConstantPoolMemberClassType(index); + } + return classType; + } + + public String getFieldName() { + if (fieldName == null) { + fieldName = cp.getConstantPoolMemberName(index); + } + return fieldName; + } + + public String getFieldType() { + if (type == null) { + type = cp.getConstantPoolMemberType(index); + } + return type; + } + } + + static PutInstruction make(ConstantPoolReader cp, int index, boolean isStatic) { + return new Lazy(isStatic ? OP_putstatic : OP_putfield, cp, index); + } + + public static PutInstruction make(String type, String className, String fieldName, boolean isStatic) { + if (type == null) { + throw new NullPointerException("type must not be null"); + } + if (className == null) { + throw new NullPointerException("className must not be null"); + } + if (fieldName == null) { + throw new NullPointerException("fieldName must not be null"); + } + return new PutInstruction(isStatic ? OP_putstatic : OP_putfield, type, className, fieldName); + } + + final public boolean equals(Object o) { + if (o instanceof PutInstruction) { + PutInstruction i = (PutInstruction) o; + return i.getFieldType().equals(getFieldType()) && i.getClassType().equals(getClassType()) + && i.getFieldName().equals(getFieldName()) && i.opcode == opcode; + } else { + return false; + } + } + + public String getClassType() { + return classType; + } + + public String getFieldType() { + return type; + } + + public String getFieldName() { + return fieldName; + } + + final public boolean isStatic() { + return opcode == OP_putstatic; + } + + final public int hashCode() { + return getClassType().hashCode() + 9011 * getClassType().hashCode() + 317 * getFieldName().hashCode() + opcode; + } + + final public int getPoppedCount() { + return isStatic() ? 1 : 2; + } + + final public String toString() { + return "Put(" + getFieldType() + "," + (isStatic() ? "STATIC" : "NONSTATIC") + "," + getClassType() + "," + getFieldName() + + ")"; + } + + final public void visit(Visitor v) { + v.visitPut(this); + } + /* (non-Javadoc) + * @see com.ibm.domo.cfg.IInstruction#isPEI() + */ + public boolean isPEI() { + return true; + } +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/ReturnInstruction.java b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/ReturnInstruction.java new file mode 100644 index 000000000..877d9ce49 --- /dev/null +++ b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/ReturnInstruction.java @@ -0,0 +1,82 @@ +/******************************************************************************* + * 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.shrikeBT; + +/** + * This instruction represents all return instructions. + */ +public final class ReturnInstruction extends Instruction { + protected ReturnInstruction(short opcode) { + this.opcode = opcode; + } + + private static final ReturnInstruction[] preallocated = preallocate(); + private static final ReturnInstruction preallocatedVoid = new ReturnInstruction(OP_return); + + private static ReturnInstruction[] preallocate() { + ReturnInstruction[] r = new ReturnInstruction[OP_areturn - OP_ireturn + 1]; + for (int i = 0; i < r.length; i++) { + r[i] = new ReturnInstruction((short) (OP_ireturn + i)); + } + return r; + } + + public static ReturnInstruction make(String type) { + if (type.equals(TYPE_void)) { + return preallocatedVoid; + } else { + int t = Util.getTypeIndex(type); + if (t < 0 || t > TYPE_Object_index) { + throw new IllegalArgumentException("Cannot return type " + type); + } + return preallocated[t]; + } + } + + public boolean equals(Object o) { + if (o instanceof ReturnInstruction) { + ReturnInstruction i = (ReturnInstruction) o; + return i.opcode == opcode; + } else { + return false; + } + } + + public boolean isFallThrough() { + return false; + } + + public int hashCode() { + return opcode + 31111; + } + + public int getPoppedCount() { + return opcode == OP_return ? 0 : 1; + } + + public String getType() { + return opcode == OP_return ? TYPE_void : indexedTypes[opcode - OP_ireturn]; + } + + public void visit(Visitor v) { + v.visitReturn(this); + } + + public String toString() { + return "Return(" + getType() + ")"; + } + /* (non-Javadoc) + * @see com.ibm.domo.cfg.IInstruction#isPEI() + */ + public boolean isPEI() { + return false; + } +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/Settings.java b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/Settings.java new file mode 100644 index 000000000..e3804f92e --- /dev/null +++ b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/Settings.java @@ -0,0 +1,25 @@ +/******************************************************************************* + * 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.shrikeBT; + +/** + * Settings for the whole ShrikeBT package. + */ +public class Settings { + /** + * Used to enable various checks if in DEBUG mode. + */ + public static final boolean DEBUG = false; + + public int hashCode() { + throw new Error("Settings.hashCode(): define a custom hash code to avoid non-determinancy"); + } +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/ShiftInstruction.java b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/ShiftInstruction.java new file mode 100644 index 000000000..42114b31c --- /dev/null +++ b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/ShiftInstruction.java @@ -0,0 +1,92 @@ +/******************************************************************************* + * 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.shrikeBT; + +/** + * ShiftInstructions are distinguished from BinaryOpInstructions because most + * binary operations in the JVM require both parameters to be the same type, but + * shifts always take one int parameter. + */ +public final class ShiftInstruction extends Instruction { + public enum Operator implements BinaryOpInstruction.IOperator { + SHL, SHR, USHR; + } + + protected ShiftInstruction(short opcode) { + this.opcode = opcode; + } + + private static final ShiftInstruction[] preallocated = preallocate(); + + private static ShiftInstruction[] preallocate() { + ShiftInstruction[] r = new ShiftInstruction[OP_lushr - OP_ishl + 1]; + for (int i = 0; i < r.length; i++) { + r[i] = new ShiftInstruction((short) (i + OP_ishl)); + } + return r; + } + + public static ShiftInstruction make(String type, Operator operator) { + int t = Util.getTypeIndex(type); + if (t < 0 || t > TYPE_long_index) { + throw new IllegalArgumentException("Cannot apply shift to type " + type); + } + + return preallocated[(operator.ordinal() - Operator.SHL.ordinal()) * 2 + t]; + } + + public boolean equals(Object o) { + if (o instanceof ShiftInstruction) { + ShiftInstruction i = (ShiftInstruction) o; + return i.opcode == opcode; + } else { + return false; + } + } + + public Operator getOperator() { + return Operator.values()[(opcode - OP_ishl) / 2]; + } + + public int hashCode() { + return opcode; + } + + public int getPoppedCount() { + return 2; + } + + public String getPushedType(String[] types) { + return getType(); + } + + public byte getPushedWordSize() { + return Util.getWordSize(getType()); + } + + public String getType() { + return indexedTypes[(opcode - OP_ishl) & 1]; + } + + public void visit(Visitor v) { + v.visitShift(this); + } + + public String toString() { + return "Shift(" + getType() + "," + getOperator() + ")"; + } + /* (non-Javadoc) + * @see com.ibm.domo.cfg.IInstruction#isPEI() + */ + public boolean isPEI() { + return false; + } +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/StoreInstruction.java b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/StoreInstruction.java new file mode 100644 index 000000000..58f5ab93b --- /dev/null +++ b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/StoreInstruction.java @@ -0,0 +1,96 @@ +/******************************************************************************* + * 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.shrikeBT; + +/** + * This class represents instructions that store to local variables. + */ +public final class StoreInstruction extends Instruction { + private int index; + + protected StoreInstruction(short opcode, int index) { + this.index = index; + this.opcode = opcode; + } + + private final static StoreInstruction[] preallocated = preallocate(); + + private static StoreInstruction[] preallocate() { + StoreInstruction[] r = new StoreInstruction[5 * 16]; + for (int p = 0; p < 5; p++) { + for (int i = 0; i < 4; i++) { + r[p * 16 + i] = new StoreInstruction((short) (OP_istore_0 + i + p * 4), i); + } + for (int i = 4; i < 16; i++) { + r[p * 16 + i] = new StoreInstruction((short) (OP_istore + p), i); + } + } + return r; + } + + public static StoreInstruction make(String type, int index) { + int t = Util.getTypeIndex(type); + if (t < 0 || t > TYPE_Object_index) { + throw new IllegalArgumentException("Cannot store local of type " + type); + } + if (index < 16) { + return preallocated[t * 16 + index]; + } else { + return new StoreInstruction((short) (OP_istore + t), index); + } + } + + /** + * @return the index of the local variable stored + */ + public int getVarIndex() { + return index; + } + + public String getType() { + if (opcode < OP_istore_0) { + return indexedTypes[opcode - OP_istore]; + } else { + return indexedTypes[(opcode - OP_istore_0) / 4]; + } + } + + public boolean equals(Object o) { + if (o instanceof StoreInstruction) { + StoreInstruction i = (StoreInstruction) o; + return i.index == index && i.opcode == opcode; + } else { + return false; + } + } + + public int hashCode() { + return opcode + index * 148091891; + } + + public int getPoppedCount() { + return 1; + } + + public String toString() { + return "LocalStore(" + getType() + "," + index + ")"; + } + + public void visit(Visitor v) { + v.visitLocalStore(this); + } + /* (non-Javadoc) + * @see com.ibm.domo.cfg.IInstruction#isPEI() + */ + public boolean isPEI() { + return false; + } +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/SwapInstruction.java b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/SwapInstruction.java new file mode 100644 index 000000000..a1f897abd --- /dev/null +++ b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/SwapInstruction.java @@ -0,0 +1,56 @@ +/******************************************************************************* + * 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.shrikeBT; + +/** + * This instruction represents the swap instruction, which swaps the two values + * on top of the working stack. + */ +public final class SwapInstruction extends Instruction { + protected SwapInstruction() { + } + + private final static SwapInstruction preallocated = new SwapInstruction(); + + public static SwapInstruction make() { + return preallocated; + } + + public boolean equals(Object o) { + if (o instanceof SwapInstruction) { + return true; + } else { + return false; + } + } + + public int hashCode() { + return 84323111; + } + + public int getPoppedCount() { + return 2; + } + + public String toString() { + return "Swap()"; + } + + public void visit(Visitor v) { + v.visitSwap(this); + } + /* (non-Javadoc) + * @see com.ibm.domo.cfg.IInstruction#isPEI() + */ + public boolean isPEI() { + return false; + } +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/SwitchInstruction.java b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/SwitchInstruction.java new file mode 100644 index 000000000..69bed9e08 --- /dev/null +++ b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/SwitchInstruction.java @@ -0,0 +1,136 @@ +/******************************************************************************* + * 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.shrikeBT; + +import java.util.Arrays; + +/** + * This instruction represents all forms of switch instructions. + */ +public final class SwitchInstruction extends Instruction { + private int[] casesAndLabels; + private int defaultLabel; + + protected SwitchInstruction(short opcode, int[] casesAndLabels, int defaultLabel) { + this.casesAndLabels = casesAndLabels; + this.defaultLabel = defaultLabel; + this.opcode = opcode; + } + + /** + * @return the label which is branched to if none of the cases match + */ + public int getDefaultLabel() { + return defaultLabel; + } + + /** + * @return an array of flattened (case, label) pairs, sorted in increasing + * order by case + */ + public int[] getCasesAndLabels() { + return casesAndLabels; + } + + /** + * Make a switch instruction. + * + * @param casesAndLabels + * an array of flattened (case, label) pairs, sorted in increasing + * order by case + * @param defaultLabel + * the default label to branch to if no cases match + */ + public static SwitchInstruction make(int[] casesAndLabels, int defaultLabel) { + short opcode = OP_tableswitch; + + for (int i = 2; i < casesAndLabels.length; i += 2) { + int curCase = casesAndLabels[i]; + int lastCase = casesAndLabels[i - 2]; + if (curCase <= lastCase) { + throw new IllegalArgumentException("Cases and labels array must be sorted by case"); + } + if (curCase != lastCase + 1) { + opcode = OP_lookupswitch; + } + } + + if (casesAndLabels.length == 0) { + opcode = OP_lookupswitch; + } + + return new SwitchInstruction(opcode, casesAndLabels, defaultLabel); + } + + public boolean isFallThrough() { + return false; + } + + public int[] getBranchTargets() { + int[] r = new int[casesAndLabels.length / 2 + 1]; + r[0] = defaultLabel; + for (int i = 1; i < r.length; i++) { + r[i] = casesAndLabels[(i - 1) * 2 + 1]; + } + return r; + } + + public Instruction redirectTargets(int[] targetMap) { + int[] cs = new int[casesAndLabels.length]; + for (int i = 0; i < cs.length; i += 2) { + cs[i] = casesAndLabels[i]; + cs[i + 1] = targetMap[casesAndLabels[i + 1]]; + } + return make(cs, targetMap[defaultLabel]); + } + + public boolean equals(Object o) { + if (o instanceof SwitchInstruction) { + SwitchInstruction i = (SwitchInstruction) o; + return i.defaultLabel == defaultLabel && Arrays.equals(i.casesAndLabels, casesAndLabels); + } else { + return false; + } + } + + public int hashCode() { + int h = defaultLabel * 1348091 + 111311; + for (int i = 0; i < casesAndLabels.length; i++) { + h += (i * 9301 + 38101) * casesAndLabels[i]; + } + return h; + } + + public int getPoppedCount() { + return 1; + } + + public String toString() { + StringBuffer b = new StringBuffer("Switch("); + b.append(defaultLabel); + for (int i = 0; i < casesAndLabels.length; i++) { + b.append(','); + b.append(casesAndLabels[i]); + } + b.append(")"); + return b.toString(); + } + + public void visit(Visitor v) { + v.visitSwitch(this); + } + /* (non-Javadoc) + * @see com.ibm.domo.cfg.IInstruction#isPEI() + */ + public boolean isPEI() { + return false; + } +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/ThrowInstruction.java b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/ThrowInstruction.java new file mode 100644 index 000000000..65cc30f86 --- /dev/null +++ b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/ThrowInstruction.java @@ -0,0 +1,56 @@ +/******************************************************************************* + * 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.shrikeBT; + +/** + * This class represents the athrow instruction. + */ +public final class ThrowInstruction extends Instruction { + private static final ThrowInstruction preallocated = new ThrowInstruction(); + + protected ThrowInstruction() { + this.opcode = OP_athrow; + } + + public static ThrowInstruction make() { + return preallocated; + } + + public boolean equals(Object o) { + return o instanceof ThrowInstruction; + } + + public boolean isFallThrough() { + return false; + } + + public int hashCode() { + return 99651; + } + + public int getPoppedCount() { + return 1; + } + + public void visit(Visitor v) { + v.visitThrow(this); + } + + public String toString() { + return "Throw()"; + } + /* (non-Javadoc) + * @see com.ibm.domo.cfg.IInstruction#isPEI() + */ + public boolean isPEI() { + return true; + } +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/UnaryOpInstruction.java b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/UnaryOpInstruction.java new file mode 100644 index 000000000..d6a6334e2 --- /dev/null +++ b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/UnaryOpInstruction.java @@ -0,0 +1,97 @@ +/******************************************************************************* + * 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.shrikeBT; + +/** + * This class represents unary operators where the result is the same type as + * the operand. + */ +public final class UnaryOpInstruction extends Instruction { + public interface IOperator {} + + public static enum Operator implements IOperator { + NEG; + + @Override + public String toString() { + return super.toString().toLowerCase(); + } + } + + protected UnaryOpInstruction(short opcode) { + this.opcode = opcode; + } + + private final static UnaryOpInstruction[] preallocated = preallocate(); + + private static UnaryOpInstruction[] preallocate() { + UnaryOpInstruction[] r = new UnaryOpInstruction[OP_dneg - OP_ineg + 1]; + for (int i = 0; i < r.length; i++) { + r[i] = new UnaryOpInstruction((short) (OP_ineg + i)); + } + return r; + } + + public static UnaryOpInstruction make(String type, Operator operator) { + int t = Util.getTypeIndex(type); + if (t < 0 || t > TYPE_double_index) { + throw new IllegalArgumentException("Type " + type + " cannot have a unary operator applied"); + } + return preallocated[t]; + } + + public boolean equals(Object o) { + if (o instanceof UnaryOpInstruction) { + UnaryOpInstruction i = (UnaryOpInstruction) o; + return i.opcode == opcode; + } else { + return false; + } + } + + public Operator getOperator() { + return Operator.NEG; + } + + public int hashCode() { + return opcode; + } + + public int getPoppedCount() { + return 1; + } + + public String getPushedType(String[] types) { + return getType(); + } + + public byte getPushedWordSize() { + return Util.getWordSize(getType()); + } + + public String getType() { + return indexedTypes[opcode - OP_ineg]; + } + + public void visit(Visitor v) { + v.visitUnaryOp(this); + } + + public String toString() { + return "UnaryOp(" + getType() + "," + getOperator() + ")"; + } + /* (non-Javadoc) + * @see com.ibm.domo.cfg.IInstruction#isPEI() + */ + public boolean isPEI() { + return false; + } +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/Util.java b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/Util.java new file mode 100644 index 000000000..61da87a71 --- /dev/null +++ b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/Util.java @@ -0,0 +1,540 @@ +/******************************************************************************* + * 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.shrikeBT; + +import java.io.IOException; +import java.io.InputStream; +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.util.Arrays; +import java.util.HashMap; + +import com.ibm.wala.shrikeBT.IInvokeInstruction.Dispatch; + +/** + * This class contains miscellaneous useful functions. + * + * In the documentation below, we refer to a 'Java class name'. These are + * formatted according to the rules for Class.forName() and Class.getName(). A + * Java class name must use '$' to separate inner class names from their + * containing class. There is no way to for Shrike to disambiguate 'A.B' + * otherwise. + */ +public final class Util { + private Util() { + // prevent instantiation + } + + /** + * @return the JVM "stack word size" for the given JVM type + */ + public static byte getWordSize(String s) { + return getWordSize(s, 0); + } + + /** + * @return the JVM "stack word size" for the given JVM type, looking at index + * 'index' + */ + public static byte getWordSize(String s, int index) { + switch (s.charAt(index)) { + case 'V': + return 0; + case 'J': + case 'D': + return 2; + default: + return 1; + } + } + + /** + * Computes the character length of the internal JVM type given by + * s.substring(i). + */ + public static int getTypeLength(String s, int i) { + switch (s.charAt(i)) { + case 'L': + return s.indexOf(';', i) - i + 1; + case '[': + return getTypeLength(s, i + 1) + 1; + default: + return 1; + } + } + + /** + * Compute the total number of JVM "stack words" occupied by the method + * parameters for method signature "type". Any "this" parameter is not + * included. + */ + public static int getParamsWordSize(String type) { + int index = 1; + int count = 0; + + if (type.indexOf(')', 1) < 0) { + throw new IllegalArgumentException("Invalid method descriptor (missing ')'): " + type); + } + while (type.charAt(index) != ')') { + count += getWordSize(type, index); + index += getTypeLength(type, index); + } + return count; + } + + /** + * Convert a fully-qualified Java class name ('.' separated) into an internal + * JVM type name ('/' separated, starting with 'L' and ending with ';'). + */ + public static String makeType(String c) { + if (c.startsWith("[")) { + return c.replace('.', '/'); + } else if (!c.endsWith(";")) { + return "L" + c.replace('.', '/') + ";"; + } else { + return c; + } + } + + /** + * Convert a fully-qualified Java type name (either primitive or class name, + * '.' separated) into an internal JVM type name (one letter for primitive and + * '/' separated, starting with 'L' and ending with ';' for class name). + */ + public static String makeTypeAll(String c) { + String alias = typeAliases.get(c); + if (alias != null) { + return alias; + } else { + return makeType(c); + } + } + + /** + * Convert a JVM type name back into a Java class name. + */ + public static String makeClass(String t) { + if (t.startsWith("[")) { + return t; + } else if (!t.startsWith("L")) { + throw new IllegalArgumentException(t + " is not a valid class type"); + } else { + return t.substring(1, t.length() - 1).replace('/', '.'); + } + } + + /** + * Convert a JVM type name (either for a primitive or a class name) into a + * Java type name. + */ + public static String makeClassAll(String t) { + String alias = classAliases.get(t); + if (alias != null) { + return alias; + } else { + return makeClass(t); + } + } + + private static HashMap classAliases; + private static HashMap typeAliases; + + private static void addAlias(String c, String t) { + typeAliases.put(c, t); + classAliases.put(t, c); + } + static { + typeAliases = new HashMap(); + classAliases = new HashMap(); + addAlias("void", "V"); + addAlias("int", "I"); + addAlias("long", "J"); + addAlias("float", "F"); + addAlias("double", "D"); + addAlias("byte", "B"); + addAlias("char", "C"); + addAlias("short", "S"); + addAlias("boolean", "Z"); + } + + /** + * Compute the JVM type name for an actual Java class. Names such as "int", + * "void", etc are also converted to their JVM type names. + */ + public static String makeType(Class c) { + String name = c.getName(); + String alias = typeAliases.get(name); + if (alias != null) { + return alias; + } else { + return makeType(name); + } + } + + /** + * Compute the number of parameters given by method signature "type". Any + * "this" parameter is not included. + */ + public static int getParamsCount(String type) { + int index = 1; + int count = 0; + + while (type.charAt(index) != ')') { + count++; + index += getTypeLength(type, index); + } + return count; + } + + /** + * Extract the types of the parameters given by method signature "type". + * + * @param thisClassType + * null if the method is static, otherwise the type of "this" + * @return an array of the parameter types in order, including "this" as the + * first parameter if thisClassType was non-null + */ + public static String[] getParamsTypes(String thisClassType, String type) { + int count = thisClassType != null ? 1 : 0; + String[] r = new String[getParamsCount(type) + count]; + int index = 1; + + if (thisClassType != null) { + r[0] = thisClassType; + } + + while (type.charAt(index) != ')') { + int len = getTypeLength(type, index); + + r[count] = type.substring(index, index + len); + count++; + index += len; + } + return r; + } + + /** + * Compute the types of the local variables on entry to a method. Similar to + * "getParamsTypes" except null array entries are inserted to account for + * unused local variables because of 2-word parameter values. + */ + public static String[] getParamsTypesInLocals(String thisClassType, String type) { + int count = thisClassType != null ? 1 : 0; + String[] r = new String[getParamsWordSize(type) + count]; + int index = 1; + + if (thisClassType != null) { + r[0] = thisClassType; + } + + while (type.charAt(index) != ')') { + int len = getTypeLength(type, index); + String t = getStackType(type.substring(index, index + len)); + + r[count] = t; + count += getWordSize(t); + index += len; + } + return r; + } + + /** + * Compute the promoted type that the JVM uses to manipulate values of type + * "t" on its working stack. + */ + public static String getStackType(String t) { + switch (t.charAt(0)) { + case 'Z': + case 'C': + case 'B': + case 'S': + return "I"; + default: + return t; + } + } + + /** + * Compute the type "array of t". + */ + public static String makeArray(String t) { + return ("[" + t).intern(); + } + + /** + * @return true iff t is an array type + */ + public static boolean isArrayType(String t) { + if (t == null) { + return false; + } else { + switch (t.charAt(0)) { + case '[': + return true; + default: + return false; + } + } + } + + /** + * @return true iff t is a primitive type + */ + public static boolean isPrimitiveType(String t) { + if (t == null) { + return false; + } else { + switch (t.charAt(0)) { + case 'L': + case '[': + return false; + default: + return true; + } + } + } + + /** + * Get the return type from a method signature. + */ + public static String getReturnType(String s) { + return s.substring(s.lastIndexOf(')') + 1); + } + + /** + * General "print an error" routine. + */ + public static void error(String s) { + System.err.println(s); + (new Error("Stack Trace")).printStackTrace(); + } + + /** + * Given a Java Method, compute the VM-style type signature. + */ + public static String computeSignature(Class[] params, Class result) { + StringBuffer buf = new StringBuffer(); + buf.append("("); + for (int i = 0; i < params.length; i++) { + buf.append(makeType(params[i])); + } + buf.append(")"); + buf.append(makeType(result)); + return buf.toString(); + } + + /** + * Make an Instruction which loads the value of a field, given its name and + * Java Class. The field type is obtained using reflection. + */ + public static GetInstruction makeGet(Class c, String name) { + try { + Field f = c.getField(name); + return GetInstruction.make(makeType(f.getType()), makeType(c), name, (f.getModifiers() & Constants.ACC_STATIC) != 0); + } catch (SecurityException e) { + throw new IllegalArgumentException(e.getMessage()); + } catch (NoSuchFieldException e) { + throw new IllegalArgumentException(e.getMessage()); + } + } + + /** + * Make an Instruction which stores the value of a field, given its name and + * Java Class. The field type is obtained using reflection. + */ + public static PutInstruction makePut(Class c, String name) { + try { + Field f = c.getField(name); + return PutInstruction.make(makeType(f.getType()), makeType(c), name, (f.getModifiers() & Constants.ACC_STATIC) != 0); + } catch (SecurityException e) { + throw new IllegalArgumentException(e.getMessage()); + } catch (NoSuchFieldException e) { + throw new IllegalArgumentException(e.getMessage()); + } + } + + private static String makeName(String name, Class[] paramTypes) { + if (paramTypes == null) { + return name; + } else { + StringBuffer buf = new StringBuffer(name); + buf.append("("); + for (int i = 0; i < paramTypes.length; i++) { + if (i > 0) { + buf.append(","); + } + buf.append(paramTypes[i].getName()); + } + buf.append(")"); + return buf.toString(); + } + } + + public static Method findMethod(Class c, String name) { + return findMethod(c, name, null); + } + + public static Method findMethod(Class c, String name, Class[] paramTypes) { + Method[] methods = c.getMethods(); + Method result = null; + for (int i = 0; i < methods.length; i++) { + Method m = methods[i]; + if (m.getName().equals(name) && (paramTypes == null || Arrays.equals(m.getParameterTypes(), paramTypes))) { + if (result != null) { + throw new IllegalArgumentException("Method " + makeName(name, paramTypes) + " is ambiguous in class " + c); + } + result = m; + } + } + return result; + } + + /** + * Make an Instruction which calls a method, given its name, Java Class, and a + * list of parameter classes to use for overload resolution. Method + * information is obtained using reflection. + */ + public static InvokeInstruction makeInvoke(Class c, String name, Class[] paramTypes) { + InvokeInstruction result = null; + + if (name.equals("")) { + Constructor[] cs = c.getConstructors(); + for (int i = 0; i < cs.length; i++) { + Constructor con = cs[i]; + if (paramTypes == null || Arrays.equals(con.getParameterTypes(), paramTypes)) { + if (result != null) { + throw new IllegalArgumentException("Constructor " + makeName(name, paramTypes) + " is ambiguous in class " + c); + } + result = InvokeInstruction.make(computeSignature(con.getParameterTypes(), Void.TYPE), makeType(c), name, Dispatch.SPECIAL); + } + } + } else { + Method m = findMethod(c, name, paramTypes); + if (m != null) { + Dispatch opcode = Dispatch.VIRTUAL; + if ((m.getModifiers() & Constants.ACC_STATIC) != 0) { + opcode = Dispatch.STATIC; + } else if (m.getDeclaringClass().isInterface()) { + opcode = Dispatch.INTERFACE; + } + result = InvokeInstruction.make(computeSignature(m.getParameterTypes(), m.getReturnType()), makeType(c), name, opcode); + } + } + + if (result == null) { + throw new IllegalArgumentException("Method " + makeName(name, paramTypes) + " is not present in class " + c); + } else { + return result; + } + } + + /** + * Make an Instruction which calls a method, given its name and Java Class. + * Method information is obtained using reflection. If there is more than one + * method with the given name, an error will be thrown. + */ + public static InvokeInstruction makeInvoke(Class c, String name) { + return makeInvoke(c, name, null); + } + + /** + * Compute the type index constant (Constants.TYPE_...) from the JVM type. + * Returns -1 if the type is not one of the predefined constants. + */ + static int getTypeIndex(String t) { + if (t == null) { + return -1; + } else { + int len = t.length(); + if (len < 1) { + return -1; + } else { + char ch = t.charAt(0); + if (ch < typeIndices.length) { + int r = typeIndices[ch]; + if (r != 4) { + if (len > 1) { + return -1; + } else { + return r; + } + } else { + return r; + } + } else { + return -1; + } + } + } + } + + private static final byte[] typeIndices = makeTypeIndices(); + + private static byte[] makeTypeIndices() { + byte[] r = new byte[128]; + for (int i = 0; i < r.length; i++) { + r[i] = -1; + } + r['I'] = 0; + r['J'] = 1; + r['F'] = 2; + r['D'] = 3; + r['L'] = 4; + r['['] = 4; + r['B'] = 5; + r['C'] = 6; + r['S'] = 7; + r['Z'] = 8; + + return r; + } + + public static void readFully(InputStream s, byte[] bytes) throws IOException { + int offset = 0; + while (offset < bytes.length) { + int r = s.read(bytes, offset, bytes.length - offset); + if (r < 0) { + throw new IOException("Class truncated"); + } + offset += r; + } + } + + public static byte[] readFully(InputStream s) throws IOException { + byte[] bytes = new byte[s.available()]; + readFully(s, bytes); + int b = s.read(); + if (b < 0) { + return bytes; + } else { + byte[] big = new byte[bytes.length * 2 + 1]; + System.arraycopy(bytes, 0, big, 0, bytes.length); + big[bytes.length] = (byte) b; + int offset = bytes.length + 1; + do { + if (big.length == offset) { + // grow array by factor of 2 + bytes = new byte[offset * 2]; + System.arraycopy(big, 0, bytes, 0, offset); + big = bytes; + } + int r = s.read(big, offset, big.length - offset); + if (r < 0) { + bytes = new byte[offset]; + System.arraycopy(big, 0, bytes, 0, offset); + return bytes; + } + offset += r; + } while (true); + } + } +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/analysis/Analyzer.java b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/analysis/Analyzer.java new file mode 100644 index 000000000..12ecf3283 --- /dev/null +++ b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/analysis/Analyzer.java @@ -0,0 +1,662 @@ +/******************************************************************************* + * 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.shrikeBT.analysis; + +import java.io.IOException; +import java.io.Writer; +import java.util.ArrayList; +import java.util.BitSet; +import java.util.List; + +import com.ibm.wala.shrikeBT.DupInstruction; +import com.ibm.wala.shrikeBT.ExceptionHandler; +import com.ibm.wala.shrikeBT.Instruction; +import com.ibm.wala.shrikeBT.LoadInstruction; +import com.ibm.wala.shrikeBT.MethodData; +import com.ibm.wala.shrikeBT.StoreInstruction; +import com.ibm.wala.shrikeBT.SwapInstruction; +import com.ibm.wala.shrikeBT.Util; + +/** + * @author roca + */ +public class Analyzer { + // inputs + protected boolean isStatic; + protected String classType; + protected String signature; + protected Instruction[] instructions; + protected ExceptionHandler[][] handlers; + protected ClassHierarchyProvider hierarchy; + + // working + protected int maxStack; + protected int maxLocals; + protected String[][] stacks; + protected String[][] locals; + protected int[] stackSizes; + protected BitSet basicBlockStarts; + protected int[][] backEdges; + + protected final static String[] noStrings = new String[0]; + protected final static int[] noEdges = new int[0]; + + public Analyzer(boolean isStatic, String classType, String signature, Instruction[] instructions, ExceptionHandler[][] handlers) { + this.classType = classType; + this.isStatic = isStatic; + this.signature = signature; + this.instructions = instructions; + this.handlers = handlers; + } + + /** + * Use class hierarchy information in 'h'. If this method is not called or h + * provides only partial hierarchy information, the verifier behaves + * optimistically. + */ + final public void setClassHierarchy(ClassHierarchyProvider h) { + this.hierarchy = h; + } + + private void addBackEdge(int from, int to) { + int[] oldEdges = backEdges[from]; + if (oldEdges == null) { + backEdges[from] = new int[] { to }; + } else if (oldEdges[oldEdges.length - 1] < 0) { + int left = 1; + int right = oldEdges.length - 1; + while (true) { + if (right - left < 2) { + if (oldEdges[left] < 0) { + break; + } else { + if (oldEdges[right] >= 0) + throw new Error("Failed binary search"); + left = right; + break; + } + } else { + int mid = (left + right) / 2; + if (oldEdges[mid] < 0) { + right = mid; + } else { + left = mid + 1; + } + } + } + oldEdges[left] = to; + } else { + int[] newEdges = new int[oldEdges.length * 2]; + System.arraycopy(oldEdges, 0, newEdges, 0, oldEdges.length); + newEdges[oldEdges.length] = to; + for (int i = oldEdges.length + 1; i < newEdges.length; i++) { + newEdges[i] = -1; + } + backEdges[from] = newEdges; + } + } + + final public int[][] getBackEdges() { + if (backEdges != null) { + return backEdges; + } + + backEdges = new int[instructions.length][]; + + for (int i = 0; i < instructions.length; i++) { + Instruction instr = instructions[i]; + int[] targets = instr.getBranchTargets(); + for (int j = 0; j < targets.length; j++) { + addBackEdge(targets[j], i); + } + ExceptionHandler[] hs = handlers[i]; + for (int j = 0; j < hs.length; j++) { + addBackEdge(hs[j].getHandler(), i); + } + } + + for (int i = 0; i < backEdges.length; i++) { + int[] back = backEdges[i]; + if (back == null) { + backEdges[i] = noEdges; + } else if (back[back.length - 1] < 0) { + int j = back.length; + while (back[j - 1] < 0) { + j--; + } + int[] newBack = new int[j]; + System.arraycopy(back, 0, newBack, 0, newBack.length); + backEdges[i] = newBack; + } + } + + return backEdges; + } + + final public boolean isSubtypeOf(String t1, String t2) { + return ClassHierarchy.isSubtypeOf(hierarchy, t1, t2) != ClassHierarchy.NO; + } + + final public String findCommonSupertype(String t1, String t2) { + return ClassHierarchy.findCommonSupertype(hierarchy, t1, t2); + } + + final public BitSet getBasicBlockStarts() { + if (basicBlockStarts != null) { + return basicBlockStarts; + } + + BitSet r = new BitSet(instructions.length); + + r.set(0); + for (int i = 0; i < instructions.length; i++) { + int[] targets = instructions[i].getBranchTargets(); + + for (int j = 0; j < targets.length; j++) { + r.set(targets[j]); + } + } + for (int i = 0; i < handlers.length; i++) { + ExceptionHandler[] hs = handlers[i]; + if (hs != null) { + for (int j = 0; j < hs.length; j++) { + r.set(hs[j].getHandler()); + } + } + } + + basicBlockStarts = r; + return r; + } + + final public Instruction[] getInstructions() { + return instructions; + } + + private void getReachableRecursive(int from, BitSet reachable, boolean followHandlers, BitSet mask) { + while (true) { + // stop if we've already visited this instruction or if we've gone outside + // the mask + if (reachable.get(from) || (mask != null && !mask.get(from))) { + return; + } + + reachable.set(from); + + Instruction instr = instructions[from]; + int[] targets = instr.getBranchTargets(); + for (int i = 0; i < targets.length; i++) { + getReachableRecursive(targets[i], reachable, followHandlers, mask); + } + + if (followHandlers) { + ExceptionHandler[] hs = handlers[from]; + for (int i = 0; i < hs.length; i++) { + getReachableRecursive(hs[i].getHandler(), reachable, followHandlers, mask); + } + } + + if (instr.isFallThrough()) { + ++from; + continue; + } + + break; + } + } + + final public BitSet getReachableFrom(int from) { + return getReachableFrom(from, true, null); + } + + final public void getReachableFromUpdate(int from, BitSet reachable, boolean followHandlers, BitSet mask) { + reachable.clear(); + getReachableRecursive(from, reachable, followHandlers, mask); + } + + final public BitSet getReachableFrom(int from, boolean followHandlers, BitSet mask) { + BitSet reachable = new BitSet(); + getReachableRecursive(from, reachable, followHandlers, mask); + return reachable; + } + + private void getReachingRecursive(int to, BitSet reaching, BitSet mask) { + while (true) { + // stop if we've already visited this instruction or if we've gone outside + // the mask + if (reaching.get(to) || (mask != null && !mask.get(to))) { + return; + } + + reaching.set(to); + + int[] targets = backEdges[to]; + for (int i = 0; i < targets.length; i++) { + getReachingRecursive(targets[i], reaching, mask); + } + + if (to > 0 && instructions[to - 1].isFallThrough()) { + --to; + continue; + } + + break; + } + } + + private void getReachingBase(int to, BitSet reaching, BitSet mask) { + int[] targets = backEdges[to]; + for (int i = 0; i < targets.length; i++) { + getReachingRecursive(targets[i], reaching, mask); + } + + if (to > 0 && instructions[to - 1].isFallThrough()) { + getReachingRecursive(to - 1, reaching, mask); + } + } + + final public void getReachingToUpdate(int to, BitSet reaching, BitSet mask) { + getBackEdges(); + reaching.clear(); + getReachingBase(to, reaching, mask); + } + + final public BitSet getReachingTo(int to, BitSet mask) { + getBackEdges(); + BitSet reaching = new BitSet(); + getReachingBase(to, reaching, mask); + return reaching; + } + + final public BitSet getReachingTo(int to) { + return getReachingTo(to, null); + } + + private void computeStackSizesAt(int[] stackSizes, int i, int size) throws FailureException { + while (true) { + if (stackSizes[i] >= 0) { + if (size != stackSizes[i]) { + throw new FailureException(i, "Stack size mismatch", null); + } + return; + } + stackSizes[i] = size; + + Instruction instr = instructions[i]; + if (instr instanceof DupInstruction) { + size += ((DupInstruction) instr).getSize(); + } else if (instr instanceof SwapInstruction) { + } else { + size -= instr.getPoppedCount(); + if (instr.getPushedWordSize() > 0) { + size++; + } + } + + int[] targets = instr.getBranchTargets(); + for (int j = 0; j < targets.length; j++) { + computeStackSizesAt(stackSizes, targets[j], size); + } + ExceptionHandler[] hs = handlers[i]; + for (int j = 0; j < hs.length; j++) { + computeStackSizesAt(stackSizes, hs[j].getHandler(), 1); + } + + if (!instr.isFallThrough()) { + return; + } + i++; + } + } + + /** + * This exception is thrown by verify() when it fails. + */ + public static final class FailureException extends Exception { + + private static final long serialVersionUID = -7663520961403117526L; + private int offset; + private String reason; + private List path; + + FailureException(int offset, String reason, List path) { + super(reason + " at offset " + offset); + this.offset = offset; + this.reason = reason; + this.path = path; + } + + /** + * @return the index of the Instruction which failed to verify + */ + public int getOffset() { + return offset; + } + + /** + * @return a description of the reason why verification failed + */ + public String getReason() { + return reason; + } + + /** + * @return a list of PathElements describing how the type that caused the + * error was propagated from its origin to the point of the error + */ + public List getPath() { + return path; + } + + void setPath(List path) { + this.path = path; + } + + /** + * Print the path to the given stream, if there is one. + */ + public void printPath(Writer w) throws IOException { + if (path != null) { + for (int i = 0; i < path.size(); i++) { + PathElement elem = path.get(i); + String[] stack = elem.stack; + String[] locals = elem.locals; + w.write("Offset " + elem.index + ": ["); + for (int j = 0; j < stack.length; j++) { + if (j > 0) { + w.write(","); + } + w.write(stack[j]); + } + w.write("], ["); + for (int j = 0; j < locals.length; j++) { + if (j > 0) { + w.write(","); + } + w.write(locals[j] == null ? "?" : locals[j]); + } + w.write("]\n"); + } + } + } + } + + public static final class PathElement { + int index; + String[] stack; + String[] locals; + + PathElement(int index, String[] stack, String[] locals) { + this.stack = (String[]) stack.clone(); + this.locals = (String[]) locals.clone(); + this.index = index; + } + + /** + * @return the bytecode offset of the instruction causing a value transfer. + */ + public int getIndex() { + return index; + } + + /** + * @return the types of the local variabls at the instruction. + */ + public String[] getLocals() { + return locals; + } + + /** + * @return the types of the working stack at the instruction. + */ + public String[] getStack() { + return stack; + } + } + + private String[] cutArray(String[] a, int len) { + if (len == 0) { + return noStrings; + } else { + String[] r = new String[len]; + System.arraycopy(a, 0, r, 0, len); + return r; + } + } + + private boolean mergeTypes(int i, String[] curStack, int curStackSize, String[] curLocals, int curLocalsSize, List path) + throws FailureException { + boolean changed = false; + + if (stacks[i] == null) { + stacks[i] = cutArray(curStack, curStackSize); + changed = true; + } else { + String[] st = stacks[i]; + if (st.length != curStackSize) { + throw new FailureException(i, "Stack size mismatch: " + st.length + ", " + curStackSize, path); + } + for (int j = 0; j < curStackSize; j++) { + String t = findCommonSupertype(st[j], curStack[j]); + if (t != st[j]) { + if (t == null) { + throw new FailureException(i, "Stack type mismatch at " + j + " (" + st[j] + " vs " + curStack[j] + ")", path); + } + st[j] = t; + changed = true; + } + } + } + + if (locals[i] == null) { + locals[i] = cutArray(curLocals, curLocalsSize); + changed = true; + } else { + String[] ls = locals[i]; + for (int j = 0; j < ls.length; j++) { + String t = findCommonSupertype(ls[j], curLocals[j]); + if (t != ls[j]) { + ls[j] = t; + changed = true; + } + } + } + + return changed; + } + + /** + * A PathElement describes a point where a value is moved from one location to + * another. + */ + private void computeTypes(int i, TypeVisitor visitor, BitSet makeTypesAt, List path) throws FailureException { + final String[] curStack = new String[maxStack]; + final String[] curLocals = new String[maxLocals]; + + while (true) { + if (path != null) { + path.add(new PathElement(i, stacks[i], locals[i])); + } + + int curStackSize = stacks[i].length; + System.arraycopy(stacks[i], 0, curStack, 0, curStackSize); + + final int[] curLocalsSize = { locals[i].length }; + System.arraycopy(locals[i], 0, curLocals, 0, curLocalsSize[0]); + + Instruction.Visitor localsUpdate = new Instruction.Visitor() { + public void visitLocalLoad(LoadInstruction instruction) { + String t = curLocals[instruction.getVarIndex()]; + curStack[0] = t; + } + + public void visitLocalStore(StoreInstruction instruction) { + int index = instruction.getVarIndex(); + curLocals[index] = curStack[0]; + if (index >= curLocalsSize[0]) { + curLocalsSize[0] = index + 1; + } + } + }; + + boolean restart = false; + while (true) { + Instruction instr = instructions[i]; + int popped = instr.getPoppedCount(); + + if (curStackSize < popped) { + throw new FailureException(i, "Stack underflow", path); + } + + if (visitor != null) { + visitor.setState(i, path, curStack, curLocals); + instr.visit(visitor); + if (!visitor.shouldContinue()) { + return; + } + } + + if (instr instanceof DupInstruction) { + DupInstruction d = (DupInstruction) instr; + int size = d.getSize(); + + System.arraycopy(curStack, popped, curStack, popped + size, curStackSize - popped); + System.arraycopy(curStack, 0, curStack, popped, size); + curStackSize += size; + } else if (instr instanceof SwapInstruction) { + String s = curStack[0]; + curStack[0] = curStack[1]; + curStack[1] = s; + } else { + String pushed = instr.getPushedType(curStack); + if (pushed != null) { + System.arraycopy(curStack, popped, curStack, 1, curStackSize - popped); + curStack[0] = Util.getStackType(pushed); + instr.visit(localsUpdate); // visit localLoad after pushing + curStackSize -= popped - 1; + } else { + instr.visit(localsUpdate); // visit localStore before popping + System.arraycopy(curStack, popped, curStack, 0, curStackSize - popped); + curStackSize -= popped; + } + } + + int[] targets = instr.getBranchTargets(); + for (int j = 0; j < targets.length; j++) { + if (mergeTypes(targets[j], curStack, curStackSize, curLocals, curLocalsSize[0], path)) { + computeTypes(targets[j], visitor, makeTypesAt, path); + } + } + + if (!instr.isFallThrough()) { + break; + } else { + i++; + if (makeTypesAt.get(i)) { + if (mergeTypes(i, curStack, curStackSize, curLocals, curLocalsSize[0], path)) { + restart = true; + break; + } + if (path != null) { + path.remove(path.size() - 1); + } + return; + } + } + } + if (!restart) { + break; + } + } + if (path != null) { + path.remove(path.size() - 1); + } + } + + public int[] getStackSizes() throws FailureException { + if (stackSizes != null) { + return stackSizes; + } + + stackSizes = new int[instructions.length]; + + for (int i = 0; i < stackSizes.length; i++) { + stackSizes[i] = -1; + } + computeStackSizesAt(stackSizes, 0, 0); + + return stackSizes; + } + + private void computeMaxLocals() { + maxLocals = locals[0].length; + for (int i = 0; i < instructions.length; i++) { + Instruction instr = instructions[i]; + if (instr instanceof LoadInstruction) { + maxLocals = Math.max(maxLocals, ((LoadInstruction) instr).getVarIndex() + 1); + } else if (instr instanceof StoreInstruction) { + maxLocals = Math.max(maxLocals, ((StoreInstruction) instr).getVarIndex() + 1); + } + } + } + + final protected void initTypeInfo() throws FailureException { + stacks = new String[instructions.length][]; + locals = new String[instructions.length][]; + + stacks[0] = noStrings; + locals[0] = Util.getParamsTypesInLocals(isStatic ? null : classType, signature); + int[] stackSizes = getStackSizes(); + maxStack = 0; + for (int i = 0; i < stackSizes.length; i++) { + maxStack = Math.max(maxStack, stackSizes[i]); + } + computeMaxLocals(); + } + + /** + * Verify the method and compute types at every program point. + * + * @throws FailureException + * the method contains invalid bytecode + */ + final public void computeTypes(TypeVisitor v, BitSet makeTypesAt, boolean wantPath) throws FailureException { + initTypeInfo(); + computeTypes(0, v, makeTypesAt, wantPath ? new ArrayList() : null); + } + + public abstract class TypeVisitor extends Instruction.Visitor { + public abstract void setState(int index, List path, String[] curStack, String[] curLocals); + + public abstract boolean shouldContinue(); + } + + /** + * @return an array indexed by instruction index; each entry is an array of + * Strings giving the types of the locals at that instruction. + */ + final public String[][] getLocalTypes() { + return locals; + } + + /** + * @return an array indexed by instruction index; each entry is an array of + * Strings giving the types of the stack elements at that instruction. + * The top of the stack is the last element of the array. + */ + final public String[][] getStackTypes() { + return stacks; + } + + public Analyzer(MethodData info) { + this(info.getIsStatic(), info.getClassType(), info.getSignature(), info.getInstructions(), info.getHandlers()); + } +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/analysis/ClassHierarchy.java b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/analysis/ClassHierarchy.java new file mode 100644 index 000000000..75b0cdafe --- /dev/null +++ b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/analysis/ClassHierarchy.java @@ -0,0 +1,414 @@ +/******************************************************************************* + * 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.shrikeBT.analysis; + +import java.util.HashSet; +import java.util.Iterator; + +import com.ibm.wala.shrikeBT.Constants; + +/** + * This class takes the raw information from a ClassHierarchyProvider and + * computes type operations (subtype check, type union). All operations are + * static. + * + * Because ClassHierarchyProvider sometimes only provides partial information, + * these routines sometimes answer "don't know". + */ +public final class ClassHierarchy { + private ClassHierarchy() { + } + + /** + * Equals Constants.NO + */ + public static final int NO = Constants.NO; + /** + * Equals Constants.YES + */ + public static final int YES = Constants.YES; + /** + * Equals Constants.MAYBE + */ + public static final int MAYBE = Constants.MAYBE; + + private static int checkSuperinterfacesContain(ClassHierarchyProvider hierarchy, String t1, String t2, HashSet visited) { + String[] ifaces = hierarchy.getSuperInterfaces(t1); + if (ifaces == null) { + return MAYBE; + } + + int r = NO; + for (int i = 0; i < ifaces.length; i++) { + String iface = ifaces[i]; + if (!visited.contains(iface)) { + visited.add(iface); + if (iface.equals(t2)) { + return YES; + } else { + int v = checkSuperinterfacesContain(hierarchy, iface, t2, visited); + if (v == YES) { + return YES; + } else if (v == MAYBE) { + r = MAYBE; + } + } + } + } + return r; + } + + private static int checkSupertypesContain(ClassHierarchyProvider hierarchy, String t1, String t2) { + int r = NO; + + String c = t1; + while (true) { + String sup = hierarchy.getSuperClass(c); + if (sup == null) { + if (!c.equals(Constants.TYPE_Object)) { + r = MAYBE; + } + break; + } + + if (sup.equals(t2)) { + return YES; + } + + c = sup; + } + + if (hierarchy.isInterface(t2) != NO) { + HashSet visited = new HashSet(); + + for (c = t1; c != null; c = hierarchy.getSuperClass(c)) { + int v = checkSuperinterfacesContain(hierarchy, c, t2, visited); + if (v == YES) { + return YES; + } else if (v == MAYBE) { + r = MAYBE; + } + } + } + + return r; + } + + private static int checkSubtypesContain(ClassHierarchyProvider hierarchy, String t1, String t2, HashSet visited) { + // No interface is a subclass of a real class + if (hierarchy.isInterface(t1) == NO && hierarchy.isInterface(t2) == YES) { + return NO; + } + + String[] subtypes = hierarchy.getSubClasses(t1); + if (subtypes == null) { + return MAYBE; + } + + int r = NO; + for (int i = 0; i < subtypes.length; i++) { + String subt = subtypes[i]; + if (!visited.contains(subt)) { + visited.add(subt); + if (subt.equals(t2)) { + return YES; + } else { + int v = checkSubtypesContain(hierarchy, subt, t2, visited); + if (v == YES) { + return YES; + } else if (v == MAYBE) { + r = MAYBE; + } + } + } + } + return r; + } + + private static int checkSubtypeOfHierarchy(ClassHierarchyProvider hierarchy, String t1, String t2) { + if (t2.equals(Constants.TYPE_Object)) { + return YES; + } else { + int v = checkSupertypesContain(hierarchy, t1, t2); + if (v == MAYBE) { + v = checkSubtypesContain(hierarchy, t2, t1, new HashSet()); + } + return v; + } + } + + /** + * Perform subtype check. + * + * @param hierarchy + * the hierarchy information to use for the decision + * @param t1 + * a type in JVM format + * @param t2 + * a type in JVM format + * @return whether t1 is a subtype of t2 (YES, NO, MAYBE) + */ + public static int isSubtypeOf(ClassHierarchyProvider hierarchy, String t1, String t2) { + if (t1 == null || t2 == null) { + return NO; + } else if (t1.equals(t2)) { + return YES; + } else if (t1.equals(Constants.TYPE_unknown) || t2.equals(Constants.TYPE_unknown)) { + return MAYBE; + } else { + switch (t1.charAt(0)) { + case 'L': + if (t1.equals(Constants.TYPE_null)) { + return YES; + } else if (t2.startsWith("[")) { + return NO; + } else if (hierarchy == null) { + return MAYBE; + } else { + return checkSubtypeOfHierarchy(hierarchy, t1, t2); + } + case '[': + if (t2.equals(Constants.TYPE_Object) || t2.equals("Ljava/io/Serializable;") || t2.equals("Ljava/lang/Cloneable;")) { + return YES; + } else if (t2.startsWith("[")) { + return isSubtypeOf(hierarchy, t1.substring(1), t2.substring(1)); + } else { + return NO; + } + default: + return NO; + } + } + } + + private static boolean insertSuperInterfaces(ClassHierarchyProvider hierarchy, String t, HashSet supers) { + String[] ifaces = hierarchy.getSuperInterfaces(t); + if (ifaces == null) { + return false; + } else { + boolean r = true; + for (int i = 0; i < ifaces.length; i++) { + String iface = ifaces[i]; + if (!supers.contains(iface)) { + supers.add(iface); + if (!insertSuperInterfaces(hierarchy, ifaces[i], supers)) { + r = false; + } + } + } + return r; + } + } + + private static boolean insertSuperClasses(ClassHierarchyProvider hierarchy, String t, HashSet supers) { + String last = t; + + for (String c = t; c != null; c = hierarchy.getSuperClass(c)) { + supers.add(c); + last = c; + } + + return last.equals(Constants.TYPE_Object); + } + + private static boolean insertSuperClassInterfaces(ClassHierarchyProvider hierarchy, String t, HashSet supers) { + boolean r = true; + + for (String c = t; c != null; c = hierarchy.getSuperClass(c)) { + if (!insertSuperInterfaces(hierarchy, c, supers)) { + r = false; + } + } + + return r; + } + + private static boolean collectDominatingSuperClasses(ClassHierarchyProvider hierarchy, String t, HashSet matches, HashSet supers) { + String last = t; + + for (String c = t; c != null; c = hierarchy.getSuperClass(c)) { + if (matches.contains(c)) { + supers.add(c); + return true; + } + last = c; + } + + return last.equals(Constants.TYPE_Object); + } + + private static boolean collectDominatingSuperInterfacesFromClass(ClassHierarchyProvider hierarchy, String t, HashSet matches, + HashSet supers) { + String[] ifaces = hierarchy.getSuperInterfaces(t); + if (ifaces == null) { + return false; + } else { + boolean r = true; + for (int i = 0; i < ifaces.length; i++) { + String iface = ifaces[i]; + if (!supers.contains(iface)) { + supers.add(iface); + if (!insertSuperInterfaces(hierarchy, ifaces[i], supers)) { + r = false; + } + } + } + return r; + } + } + + private static boolean collectDominatingSuperInterfaces(ClassHierarchyProvider hierarchy, String t, HashSet matches, + HashSet supers) { + boolean r = true; + + for (String c = t; c != null && !supers.contains(c); c = hierarchy.getSuperClass(c)) { + if (!collectDominatingSuperInterfacesFromClass(hierarchy, c, matches, supers)) { + r = false; + } + } + + return r; + } + + private static String findCommonSupertypeHierarchy(ClassHierarchyProvider hierarchy, String t1, String t2) { + if (isSubtypeOf(hierarchy, t1, t2) == YES) { + return t2; + } else if (isSubtypeOf(hierarchy, t2, t1) == YES) { + return t1; + } + + HashSet t1Supers = new HashSet(); + t1Supers.add(Constants.TYPE_Object); + boolean t1ExactClasses = insertSuperClasses(hierarchy, t1, t1Supers); + int t1ClassCount = t1Supers.size(); + boolean t1ExactInterfaces = insertSuperClassInterfaces(hierarchy, t1, t1Supers); + + HashSet t2Supers = new HashSet(); + boolean t2ExactClasses = collectDominatingSuperClasses(hierarchy, t2, t1Supers, t2Supers); + + if (t2Supers.size() == 0) { + // we didn't find a common superclass, so we don't know what it might be + return Constants.TYPE_unknown; + } // otherwise we know for sure what the common superclass is + + boolean t2ExactInterfaces; + if (t1ExactInterfaces && t1ExactClasses && t1Supers.size() - t1ClassCount == 0) { + // t1 doesn't have any interfaces so we don't need to search t2's + // interfaces + t2ExactInterfaces = true; + } else { + t2ExactInterfaces = collectDominatingSuperInterfaces(hierarchy, t2, t1Supers, t2Supers); + if (!t1ExactInterfaces && t2Supers.size() != 1) { + // we found an interface; it might also apply to t1; must bail + return Constants.TYPE_unknown; + } + } + + if (!t2ExactClasses || !t2ExactInterfaces) { + // there may be some common interfaces that we don't know about + return ""; + } + + for (Iterator iter = t2Supers.iterator(); iter.hasNext();) { + String element = iter.next(); + boolean subsumed = false; + + for (Iterator iterator = t2Supers.iterator(); iterator.hasNext();) { + String element2 = iterator.next(); + if (element != element2 && isSubtypeOf(hierarchy, element2, element) == YES) { + subsumed = true; + break; + } + } + + if (subsumed) { + iter.remove(); + } + } + + if (t2Supers.size() == 1) { + return t2Supers.iterator().next(); + } else if (t2Supers.size() == 0) { + return Constants.TYPE_Object; + } else { + return Constants.TYPE_unknown; // some non-representable combination of + // class and interfaces + } + } + + /** + * Compute the most specific common supertype. + * + * @param hierarchy + * the hierarchy information to use for the decision + * @param t1 + * a type in JVM format + * @param t2 + * a type in JVM format + * @return the most specific common supertype of t1 and t2, or TYPE_unknown if + * it cannot be determined or cannot be represented as a Java type, or + * null if there is no common supertype + */ + public static String findCommonSupertype(ClassHierarchyProvider hierarchy, String t1, String t2) { + if (t1 == null || t2 == null) { + return null; + } else if (t1.equals(t2)) { + return t1; + } else if (t1.equals(Constants.TYPE_unknown) || t2.equals(Constants.TYPE_unknown)) { + return Constants.TYPE_unknown; + } else { + if (t2.charAt(0) == '[') { // put array into t1 + String t = t1; + t1 = t2; + t2 = t; + } + + switch (t1.charAt(0)) { + case 'L': + // two non-array types + // if either one is constant null, return the other one + if (t1.equals(Constants.TYPE_null)) { + return t2; + } else if (t2.equals(Constants.TYPE_null)) { + return t1; + } else if (hierarchy == null) { + // don't have a class hierarchy + return Constants.TYPE_unknown; + } else { + return findCommonSupertypeHierarchy(hierarchy, t1, t2); + } + case '[': { + char ch2 = t2.charAt(0); + if (ch2 == '[') { + char ch1_1 = t1.charAt(1); + if (ch1_1 == '[' || ch1_1 == 'L') { + return "[" + findCommonSupertype(hierarchy, t1.substring(1), t2.substring(1)); + } else { + return Constants.TYPE_Object; + } + } else if (ch2 == 'L') { + if (t2.equals(Constants.TYPE_null)) { + return t1; + } else if (t2.equals("Ljava/io/Serializable;") || t2.equals("Ljava/lang/Cloneable;")) { + return t2; + } else { + return Constants.TYPE_Object; + } + } else { + return null; + } + } + default: + return null; + } + } + } +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/analysis/ClassHierarchyProvider.java b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/analysis/ClassHierarchyProvider.java new file mode 100644 index 000000000..d618beece --- /dev/null +++ b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/analysis/ClassHierarchyProvider.java @@ -0,0 +1,42 @@ +/******************************************************************************* + * 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.shrikeBT.analysis; + +/** + * This interface provides information about the class hierarchy to some + * consumer, such as a bytecode verifier. + * + * All class names are given in JVM type format, e.g., Ljava/lang/Object;. + */ +public interface ClassHierarchyProvider { + /** + * @return the superclass of the given class, or null if the superclass is not + * known or cl is java.lang.Object + */ + public String getSuperClass(String cl); + + /** + * @return the superinterfaces of the given class, or null if they are not + * known + */ + public String[] getSuperInterfaces(String cl); + + /** + * @return the complete set of direct subclasses or implementors of cl, or + * null if the complete set is not known + */ + public String[] getSubClasses(String cl); + + /** + * @return whether or not cl is an interface, or Constants.MAYBE if not known + */ + public int isInterface(String cl); +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/analysis/ClassHierarchyStore.java b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/analysis/ClassHierarchyStore.java new file mode 100644 index 000000000..bca99ca06 --- /dev/null +++ b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/analysis/ClassHierarchyStore.java @@ -0,0 +1,114 @@ +/******************************************************************************* + * 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.shrikeBT.analysis; + +import java.util.HashMap; +import java.util.Iterator; + +import com.ibm.wala.shrikeBT.Constants; + +/** + * This implementation of ClassHierarchyProvider is a simple writable data + * structure representing a class hierarchy. You call setClassInfo to record + * information about a class. + */ +public final class ClassHierarchyStore implements ClassHierarchyProvider { + private static final String[] noClasses = new String[0]; + + final static class ClassInfo { + boolean isInterface; + boolean isFinal; + String superClass; + String[] superInterfaces; + + ClassInfo(boolean isInterface, boolean isFinal, String superClass, String[] superInterfaces) { + this.isInterface = isInterface; + this.isFinal = isFinal; + this.superClass = superClass; + this.superInterfaces = superInterfaces; + } + } + + private HashMap contents = new HashMap(); + + /** + * Create an empty store. + */ + public ClassHierarchyStore() { + } + + /** + * Append some class information to the store. + * + * @param cl + * the JVM type of the class being added (e.g., Ljava/lang/Object;) + * @param isInterface + * true iff it's an interface + * @param isFinal + * true iff it's final + * @param superClass + * the JVM type of the superclass, or null if this is Object + * @param superInterfaces + * the JVM types of its implemented interfaces + */ + public void setClassInfo(String cl, boolean isInterface, boolean isFinal, String superClass, String[] superInterfaces) { + if (superClass != null && superClass.equals(cl)) { + throw new Error("Class " + cl + " cannot be its own superclass"); + } + contents.put(cl, new ClassInfo(isInterface, isFinal, superClass, superInterfaces)); + } + + /** + * Delete the class information from the store. + */ + public void removeClassInfo(String cl) { + contents.remove(cl); + } + + /** + * Iterate through all classes in the store. + */ + public Iterator iterateOverClasses() { + return contents.keySet().iterator(); + } + + /** + * @see ClassHierarchyProvider#getSuperClass(String) + */ + public String getSuperClass(String cl) { + ClassInfo info = contents.get(cl); + return info == null ? null : info.superClass; + } + + /* + * @see ClassHierarchyProvider#getSuperInterfaces(String) + */ + public String[] getSuperInterfaces(String cl) { + ClassInfo info = contents.get(cl); + return info == null ? null : info.superInterfaces; + } + + /* + * @see ClassHierarchyProvider#getSubClasses(String) + */ + public String[] getSubClasses(String cl) { + ClassInfo info = contents.get(cl); + return (info == null || !info.isFinal) ? null : noClasses; + } + + /* + * @see ClassHierarchyProvider#isInterface(String) + */ + public int isInterface(String cl) { + ClassInfo info = contents.get(cl); + return info == null ? Constants.MAYBE : (info.isInterface ? Constants.YES : Constants.NO); + } +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/analysis/Verifier.java b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/analysis/Verifier.java new file mode 100644 index 000000000..2651ad901 --- /dev/null +++ b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/analysis/Verifier.java @@ -0,0 +1,298 @@ +/******************************************************************************* + * 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.shrikeBT.analysis; + +import java.util.BitSet; +import java.util.List; + +import com.ibm.wala.shrikeBT.ArrayLengthInstruction; +import com.ibm.wala.shrikeBT.ArrayLoadInstruction; +import com.ibm.wala.shrikeBT.ArrayStoreInstruction; +import com.ibm.wala.shrikeBT.BinaryOpInstruction; +import com.ibm.wala.shrikeBT.CheckCastInstruction; +import com.ibm.wala.shrikeBT.ComparisonInstruction; +import com.ibm.wala.shrikeBT.ConditionalBranchInstruction; +import com.ibm.wala.shrikeBT.ConstantInstruction; +import com.ibm.wala.shrikeBT.Constants; +import com.ibm.wala.shrikeBT.ConversionInstruction; +import com.ibm.wala.shrikeBT.DupInstruction; +import com.ibm.wala.shrikeBT.ExceptionHandler; +import com.ibm.wala.shrikeBT.GetInstruction; +import com.ibm.wala.shrikeBT.GotoInstruction; +import com.ibm.wala.shrikeBT.InstanceofInstruction; +import com.ibm.wala.shrikeBT.Instruction; +import com.ibm.wala.shrikeBT.InvokeInstruction; +import com.ibm.wala.shrikeBT.LoadInstruction; +import com.ibm.wala.shrikeBT.MethodData; +import com.ibm.wala.shrikeBT.MonitorInstruction; +import com.ibm.wala.shrikeBT.NewInstruction; +import com.ibm.wala.shrikeBT.PopInstruction; +import com.ibm.wala.shrikeBT.PutInstruction; +import com.ibm.wala.shrikeBT.ReturnInstruction; +import com.ibm.wala.shrikeBT.ShiftInstruction; +import com.ibm.wala.shrikeBT.StoreInstruction; +import com.ibm.wala.shrikeBT.SwitchInstruction; +import com.ibm.wala.shrikeBT.ThrowInstruction; +import com.ibm.wala.shrikeBT.UnaryOpInstruction; +import com.ibm.wala.shrikeBT.Util; + +/** + * This class typechecks intermediate code. It's very easy to use: + * + *
                              + * 
                              + *      MethodData md = ...;
                              + *      try {
                              + *          (new Verifier(md)).verify();
                              + *      } catch (Verifier.FailureException ex) {
                              + *          System.out.println("Verification failed at instruction "
                              + *              + ex.getOffset() + ": " + ex.getReason());
                              + *      }
                              + *  
                              + * 
                              + * + * For full verification you need to provide class hierarchy information using + * setClassHierarchy. Without this information, we can't compute the exact types + * of variables at control flow merge points. If you don't provide a hierarchy, + * or the hierarchy you provide is partial, then the Verifier will be + * optimistic. + * + * This method can also be used to gather type information for every stack and + * local variable at every program point. Just call computeTypes() instead of + * verify() and then retrieve the results with getLocalTypes() and + * getStackTypes(). + */ +public final class Verifier extends Analyzer { + final class VerifyVisitor extends TypeVisitor { + private int curIndex; + private List curPath; + private FailureException ex; + private String[] curStack; + private String[] curLocals; + + VerifyVisitor() { + } + + public void setState(int offset, List path, String[] curStack, String[] curLocals) { + curIndex = offset; + curPath = path; + this.curStack = curStack; + this.curLocals = curLocals; + } + + public boolean shouldContinue() { + return ex == null; + } + + void checkError() throws FailureException { + if (ex != null) { + throw ex; + } + } + + private void checkStackSubtype(int i, String t) { + if (!isSubtypeOf(curStack[i], Util.getStackType(t))) { + ex = new FailureException(curIndex, "Expected type " + t + " at stack " + i + ", got " + curStack[i], curPath); + } + } + + private void checkArrayStackSubtype(int i, String t) { + if (!t.equals(Constants.TYPE_byte) || !"[Z".equals(curStack[i])) { + checkStackSubtype(i, Util.makeArray(t)); + } + } + + public void visitConstant(ConstantInstruction instruction) { + // make sure that constants are checked + instruction.getValue(); + } + + public void visitGoto(GotoInstruction instruction) { + } + + public void visitLocalLoad(LoadInstruction instruction) { + String t = curLocals[instruction.getVarIndex()]; + if (t == null) { + ex = new FailureException(curIndex, "Local variable " + instruction.getVarIndex() + " is not defined", curPath); + } + if (!isSubtypeOf(t, instruction.getType())) { + ex = new FailureException(curIndex, "Expected type " + instruction.getType() + " for local " + instruction.getVarIndex() + + ", got " + t, curPath); + } + } + + public void visitLocalStore(StoreInstruction instruction) { + checkStackSubtype(0, instruction.getType()); + } + + public void visitArrayLoad(ArrayLoadInstruction instruction) { + checkStackSubtype(0, Constants.TYPE_int); + checkArrayStackSubtype(1, instruction.getType()); + } + + public void visitArrayStore(ArrayStoreInstruction instruction) { + checkStackSubtype(0, instruction.getType()); + checkStackSubtype(1, Constants.TYPE_int); + checkArrayStackSubtype(2, instruction.getType()); + } + + public void visitPop(PopInstruction instruction) { + } + + public void visitDup(DupInstruction instruction) { + } + + public void visitBinaryOp(BinaryOpInstruction instruction) { + checkStackSubtype(0, instruction.getType()); + checkStackSubtype(1, instruction.getType()); + } + + public void visitUnaryOp(UnaryOpInstruction instruction) { + checkStackSubtype(0, instruction.getType()); + } + + public void visitShift(ShiftInstruction instruction) { + checkStackSubtype(0, Constants.TYPE_int); + checkStackSubtype(1, instruction.getType()); + } + + public void visitConversion(ConversionInstruction instruction) { + checkStackSubtype(0, instruction.getFromType()); + } + + public void visitComparison(ComparisonInstruction instruction) { + checkStackSubtype(0, instruction.getType()); + checkStackSubtype(1, instruction.getType()); + } + + public void visitConditionalBranch(ConditionalBranchInstruction instruction) { + checkStackSubtype(0, instruction.getType()); + checkStackSubtype(1, instruction.getType()); + } + + public void visitSwitch(SwitchInstruction instruction) { + checkStackSubtype(0, Constants.TYPE_int); + } + + public void visitReturn(ReturnInstruction instruction) { + if (instruction.getType() != Constants.TYPE_void) { + checkStackSubtype(0, instruction.getType()); + checkStackSubtype(0, Util.getReturnType(signature)); + } + } + + public void visitGet(GetInstruction instruction) { + // make sure constant pool entries are dereferenced + String classType = instruction.getClassType(); + + if (!instruction.isStatic()) { + checkStackSubtype(0, classType); + } + } + + public void visitPut(PutInstruction instruction) { + // make sure constant pool entries are dereferenced + String classType = instruction.getClassType(); + String type = instruction.getFieldType(); + + checkStackSubtype(0, type); + if (!instruction.isStatic()) { + checkStackSubtype(1, classType); + } + } + + public void visitInvoke(InvokeInstruction instruction) { + // make sure constant pool entries are dereferenced + String classType = instruction.getClassType(); + String signature = instruction.getMethodSignature(); + + String thisClass = instruction.getInvocationMode() == Constants.OP_invokestatic ? null : classType; + String[] params = Util.getParamsTypes(thisClass, signature); + + for (int i = 0; i < params.length; i++) { + checkStackSubtype(i, params[params.length - 1 - i]); + } + } + + public void visitNew(NewInstruction instruction) { + for (int i = 0; i < instruction.getArrayBoundsCount(); i++) { + checkStackSubtype(i, Constants.TYPE_int); + } + // make sure constant is dereferenced + instruction.getType(); + } + + public void visitArrayLength(ArrayLengthInstruction instruction) { + if (!curStack[0].equals(Constants.TYPE_null) && !Util.isArrayType(curStack[0])) { + ex = new FailureException(curIndex, "Expected array type at stack 0, got " + curStack[0], curPath); + } + } + + public void visitThrow(ThrowInstruction instruction) { + checkStackSubtype(0, Constants.TYPE_Throwable); + } + + public void visitMonitor(MonitorInstruction instruction) { + checkStackSubtype(0, Constants.TYPE_Object); + } + + public void visitCheckCast(CheckCastInstruction instruction) { + checkStackSubtype(0, Constants.TYPE_Object); + // make sure constant is dereferenced + instruction.getType(); + } + + public void visitInstanceof(InstanceofInstruction instruction) { + checkStackSubtype(0, Constants.TYPE_Object); + // make sure constant is dereferenced + instruction.getType(); + } + } + + /** + * Initialize a verifier. + */ + public Verifier(boolean isStatic, String classType, String signature, Instruction[] instructions, ExceptionHandler[][] handlers) { + super(isStatic, classType, signature, instructions, handlers); + } + + /** + * Initialize a verifier. + */ + public Verifier(MethodData info) { + super(info); + } + + /** + * Try to verify the method. If verification is unsuccessful, we throw an + * exception. + * + * @throws FailureException + * the method contains invalid bytecode + */ + public void verify() throws FailureException { + VerifyVisitor v = new VerifyVisitor(); + computeTypes(v, getBasicBlockStarts(), true); + v.checkError(); + } + + public void verifyCollectAll() throws FailureException { + VerifyVisitor v = new VerifyVisitor(); + BitSet all = new BitSet(instructions.length); + all.set(0, instructions.length); + computeTypes(v, all, true); + v.checkError(); + } + + public void computeTypes() throws FailureException { + computeTypes(null, getBasicBlockStarts(), false); + } +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/info/InstructionTypeCounter.java b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/info/InstructionTypeCounter.java new file mode 100644 index 000000000..b841ed8e1 --- /dev/null +++ b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/info/InstructionTypeCounter.java @@ -0,0 +1,349 @@ +/******************************************************************************* + * 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.shrikeBT.info; + +import com.ibm.wala.shrikeBT.ArrayLengthInstruction; +import com.ibm.wala.shrikeBT.ArrayLoadInstruction; +import com.ibm.wala.shrikeBT.ArrayStoreInstruction; +import com.ibm.wala.shrikeBT.BinaryOpInstruction; +import com.ibm.wala.shrikeBT.CheckCastInstruction; +import com.ibm.wala.shrikeBT.ComparisonInstruction; +import com.ibm.wala.shrikeBT.ConditionalBranchInstruction; +import com.ibm.wala.shrikeBT.ConstantInstruction; +import com.ibm.wala.shrikeBT.ConversionInstruction; +import com.ibm.wala.shrikeBT.DupInstruction; +import com.ibm.wala.shrikeBT.ExceptionHandler; +import com.ibm.wala.shrikeBT.GetInstruction; +import com.ibm.wala.shrikeBT.GotoInstruction; +import com.ibm.wala.shrikeBT.InstanceofInstruction; +import com.ibm.wala.shrikeBT.Instruction; +import com.ibm.wala.shrikeBT.InvokeInstruction; +import com.ibm.wala.shrikeBT.LoadInstruction; +import com.ibm.wala.shrikeBT.MethodData; +import com.ibm.wala.shrikeBT.MonitorInstruction; +import com.ibm.wala.shrikeBT.NewInstruction; +import com.ibm.wala.shrikeBT.PopInstruction; +import com.ibm.wala.shrikeBT.PutInstruction; +import com.ibm.wala.shrikeBT.ReturnInstruction; +import com.ibm.wala.shrikeBT.ShiftInstruction; +import com.ibm.wala.shrikeBT.StoreInstruction; +import com.ibm.wala.shrikeBT.SwapInstruction; +import com.ibm.wala.shrikeBT.SwitchInstruction; +import com.ibm.wala.shrikeBT.ThrowInstruction; +import com.ibm.wala.shrikeBT.UnaryOpInstruction; + +/** + * This method annotation counts the number of instructions of each type + * (according to each Instruction subclass). + * + * The get...Count methods are the only methods needed by clients. These methods + * check to see if the MethodData object already has an InstructionTypeCounter + * annotation before recomputing the counts and returning the desired count. + */ +public class InstructionTypeCounter implements MethodData.Results { + private final static String key = InstructionTypeCounter.class.getName(); + + private int countMonitors; + private int countGets; + private int countPuts; + private int countArrayLoads; + private int countArrayStores; + private int countInvokes; + private int countArrayLengths; + private int countBinaryOps; + private int countCheckCasts; + private int countComparisons; + private int countConditionalBranches; + private int countConstants; + private int countConversions; + private int countDups; + private int countGotos; + private int countInstanceOfs; + private int countLocalLoads; + private int countLocalStores; + private int countNews; + private int countPops; + private int countReturns; + private int countShifts; + private int countSwaps; + private int countSwitches; + private int countThrows; + private int countUnaryOps; + + InstructionTypeCounter(MethodData info) { + recalculateFrom(info.getInstructions()); + } + + private void recalculateFrom(Instruction[] instructions) { + countMonitors = 0; + countGets = 0; + countPuts = 0; + countArrayLoads = 0; + countArrayStores = 0; + countInvokes = 0; + countArrayLengths = 0; + countBinaryOps = 0; + countCheckCasts = 0; + countComparisons = 0; + countConditionalBranches = 0; + countConstants = 0; + countConversions = 0; + countDups = 0; + countGotos = 0; + countInstanceOfs = 0; + countLocalLoads = 0; + countLocalStores = 0; + countNews = 0; + countPops = 0; + countReturns = 0; + countShifts = 0; + countSwaps = 0; + countSwitches = 0; + countThrows = 0; + countUnaryOps = 0; + + Instruction.Visitor visitor = new Instruction.Visitor() { + public void visitArrayLength(ArrayLengthInstruction instruction) { + countArrayLengths++; + } + + public void visitBinaryOp(BinaryOpInstruction instruction) { + countBinaryOps++; + } + + public void visitCheckCast(CheckCastInstruction instruction) { + countCheckCasts++; + } + + public void visitComparison(ComparisonInstruction instruction) { + countComparisons++; + } + + public void visitConditionalBranch(ConditionalBranchInstruction instruction) { + countConditionalBranches++; + } + + public void visitConstant(ConstantInstruction instruction) { + countConstants++; + } + + public void visitConversion(ConversionInstruction instruction) { + countConversions++; + } + + public void visitDup(DupInstruction instruction) { + countDups++; + } + + public void visitGoto(GotoInstruction instruction) { + countGotos++; + } + + public void visitInstanceof(InstanceofInstruction instruction) { + countInstanceOfs++; + } + + public void visitLocalLoad(LoadInstruction instruction) { + countLocalLoads++; + } + + public void visitLocalStore(StoreInstruction instruction) { + countLocalStores++; + } + + public void visitNew(NewInstruction instruction) { + countNews++; + } + + public void visitPop(PopInstruction instruction) { + countPops++; + } + + public void visitReturn(ReturnInstruction instruction) { + countReturns++; + } + + public void visitShift(ShiftInstruction instruction) { + countShifts++; + } + + public void visitSwap(SwapInstruction instruction) { + countSwaps++; + } + + public void visitSwitch(SwitchInstruction instruction) { + countSwitches++; + } + + public void visitThrow(ThrowInstruction instruction) { + countThrows++; + } + + public void visitUnaryOp(UnaryOpInstruction instruction) { + countUnaryOps++; + } + + public void visitArrayLoad(ArrayLoadInstruction instruction) { + countArrayLoads++; + } + + public void visitArrayStore(ArrayStoreInstruction instruction) { + countArrayStores++; + } + + public void visitGet(GetInstruction instruction) { + countGets++; + } + + public void visitPut(PutInstruction instruction) { + countPuts++; + } + + public void visitMonitor(MonitorInstruction instruction) { + countMonitors++; + } + + public void visitInvoke(InvokeInstruction instruction) { + countInvokes++; + } + }; + + for (int i = 0; i < instructions.length; i++) { + instructions[i].visit(visitor); + } + } + + /** + * Whenever the underlying method is updated, we'll throw away our counts so + * they can be reconstructed from scratch next time. + * + * This is not to be called by clients. + */ + public boolean notifyUpdate(MethodData info, Instruction[] newInstructions, ExceptionHandler[][] newHandlers, + int[] newInstructionMap) { + // just throw this away and we'll recalculate from scratch if necessary + return true; + } + + public static int getArrayLoadCount(MethodData info) { + return getCounter(info).countArrayLoads; + } + + public static int getArrayStoreCount(MethodData info) { + return getCounter(info).countArrayStores; + } + + public static int getGetCount(MethodData info) { + return getCounter(info).countGets; + } + + public static int getPutCount(MethodData info) { + return getCounter(info).countPuts; + } + + public static int getMonitorCount(MethodData info) { + return getCounter(info).countMonitors; + } + + public static int getInvokeCount(MethodData info) { + return getCounter(info).countInvokes; + } + + public static int getComparisonCount(MethodData info) { + return getCounter(info).countComparisons; + } + + public static int getArrayLengthCount(MethodData info) { + return getCounter(info).countArrayLengths; + } + + public static int getConstantCount(MethodData info) { + return getCounter(info).countConstants; + } + + public static int getShiftCount(MethodData info) { + return getCounter(info).countShifts; + } + + public static int getSwitchesCount(MethodData info) { + return getCounter(info).countSwitches; + } + + public static int getSwapCount(MethodData info) { + return getCounter(info).countSwaps; + } + + public static int getBinaryOpCount(MethodData info) { + return getCounter(info).countBinaryOps; + } + + public static int getCheckCastCount(MethodData info) { + return getCounter(info).countCheckCasts; + } + + public static int getThrowCount(MethodData info) { + return getCounter(info).countThrows; + } + + public static int getConditionalBranchCount(MethodData info) { + return getCounter(info).countConditionalBranches; + } + + public static int getConversionCount(MethodData info) { + return getCounter(info).countConversions; + } + + public static int getDupCount(MethodData info) { + return getCounter(info).countDups; + } + + public static int getGotoCount(MethodData info) { + return getCounter(info).countGotos; + } + + public static int getReturnCount(MethodData info) { + return getCounter(info).countReturns; + } + + public static int getInstanceOfCount(MethodData info) { + return getCounter(info).countInstanceOfs; + } + + public static int getLocalLoadCount(MethodData info) { + return getCounter(info).countLocalLoads; + } + + public static int getLocalStoreCount(MethodData info) { + return getCounter(info).countLocalStores; + } + + public static int getNewCount(MethodData info) { + return getCounter(info).countNews; + } + + public static int getPopCount(MethodData info) { + return getCounter(info).countPops; + } + + public static int getUnaryOpCount(MethodData info) { + return getCounter(info).countUnaryOps; + } + + private static InstructionTypeCounter getCounter(MethodData info) { + InstructionTypeCounter c = (InstructionTypeCounter) info.getInfo(key); + if (c == null) { + c = new InstructionTypeCounter(info); + info.putInfo(key, c); + } + + return c; + } +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/info/LocalAllocator.java b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/info/LocalAllocator.java new file mode 100644 index 000000000..ffc27fbe7 --- /dev/null +++ b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/info/LocalAllocator.java @@ -0,0 +1,98 @@ +/******************************************************************************* + * 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.shrikeBT.info; + +import com.ibm.wala.shrikeBT.ExceptionHandler; +import com.ibm.wala.shrikeBT.Instruction; +import com.ibm.wala.shrikeBT.LoadInstruction; +import com.ibm.wala.shrikeBT.MethodData; +import com.ibm.wala.shrikeBT.StoreInstruction; +import com.ibm.wala.shrikeBT.Util; + +/** + * This method annotation parcels out fresh local variables for use as + * temporaries by instrumentation code. It assumes that local variables are not + * allocated by any other mechanism. + */ +public class LocalAllocator implements MethodData.Results { + private final static String key = LocalAllocator.class.getName(); + + private int nextLocal; + + LocalAllocator(MethodData info) { + recalculateFrom(info); + } + + private void recalculateFrom(MethodData info) { + Instruction[] instructions = info.getInstructions(); + final int[] max = { Util.getParamsWordSize(info.getSignature()) + (info.getIsStatic() ? 0 : 1) }; + + Instruction.Visitor visitor = new Instruction.Visitor() { + public void visitLocalLoad(LoadInstruction instruction) { + int v = instruction.getVarIndex() + Util.getWordSize(instruction.getType()); + if (v > max[0]) { + max[0] = v; + } + } + + public void visitLocalStore(StoreInstruction instruction) { + int v = instruction.getVarIndex() + Util.getWordSize(instruction.getType()); + if (v > max[0]) { + max[0] = v; + } + } + }; + + for (int i = 0; i < instructions.length; i++) { + instructions[i].visit(visitor); + } + + nextLocal = max[0]; + } + + private int allocateLocals(int count) { + int r = nextLocal; + nextLocal += count; + return r; + } + + /** + * This should not be called by clients. + */ + public boolean notifyUpdate(MethodData info, Instruction[] newInstructions, ExceptionHandler[][] newHandlers, + int[] newInstructionMap) { + return false; + } + + /** + * Allocates a new local variable of the specified type. + */ + public static int allocate(MethodData info, int count) { + LocalAllocator l = (LocalAllocator) info.getInfo(key); + if (l == null) { + l = new LocalAllocator(info); + info.putInfo(key, l); + } + + return l.allocateLocals(count); + } + + public static int allocate(MethodData info, String type) { + return allocate(info, type == null ? 2 : Util.getWordSize(type)); + } + + /** + * Allocates a new local that will fit any type. + */ + public static int allocate(MethodData info) { + return allocate(info, null); + } +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/info/ThisAssignmentChecker.java b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/info/ThisAssignmentChecker.java new file mode 100644 index 000000000..9425579d9 --- /dev/null +++ b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/info/ThisAssignmentChecker.java @@ -0,0 +1,70 @@ +/******************************************************************************* + * 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.shrikeBT.info; + +import com.ibm.wala.shrikeBT.ExceptionHandler; +import com.ibm.wala.shrikeBT.Instruction; +import com.ibm.wala.shrikeBT.MethodData; +import com.ibm.wala.shrikeBT.StoreInstruction; + +/** + * This method annotation checks to see whether "this" is assigned to by the + * method. The result is cached in an annotation. + */ +public class ThisAssignmentChecker implements MethodData.Results { + private final static String key = ThisAssignmentChecker.class.getName(); + + private boolean assignmentToThis; + + ThisAssignmentChecker(MethodData info) { + recalculateFrom(info); + } + + private void recalculateFrom(MethodData info) { + assignmentToThis = false; + + if (!info.getIsStatic()) { + Instruction[] instructions = info.getInstructions(); + + for (int i = 0; i < instructions.length; i++) { + Instruction instr = instructions[i]; + if (instr instanceof StoreInstruction) { + StoreInstruction st = (StoreInstruction) instr; + if (st.getVarIndex() == 0) { + assignmentToThis = true; + } + } + } + } + } + + /** + * This should not be called by any client. + */ + public boolean notifyUpdate(MethodData info, Instruction[] newInstructions, ExceptionHandler[][] newHandlers, + int[] newInstructionMap) { + // just throw this away and we'll recalculate from scratch if necessary + return true; + } + + /** + * @return true iff 'this' is assigned to by the method + */ + public static boolean isThisAssigned(MethodData info) { + ThisAssignmentChecker c = (ThisAssignmentChecker) info.getInfo(key); + if (c == null) { + c = new ThisAssignmentChecker(info); + info.putInfo(key, c); + } + + return c.assignmentToThis; + } +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/shrikeCT/CTCompiler.java b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/shrikeCT/CTCompiler.java new file mode 100644 index 000000000..d6794f545 --- /dev/null +++ b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/shrikeCT/CTCompiler.java @@ -0,0 +1,88 @@ +/******************************************************************************* + * 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.shrikeBT.shrikeCT; + +import java.util.Random; + +import com.ibm.wala.shrikeBT.Compiler; +import com.ibm.wala.shrikeBT.MethodData; +import com.ibm.wala.shrikeCT.ClassWriter; + +/** + * This class lets you compile ShrikeBT intermediate code into real Java + * bytecodes using ShrikeCT. + */ +final public class CTCompiler extends Compiler { + private ClassWriter cw; + + /** + * Compile 'md' into the class given by 'cw'. + */ + public CTCompiler(ClassWriter cw, MethodData md) { + super(md); + this.cw = cw; + } + + protected int allocateConstantPoolInteger(int v) { + return cw.addCPInt(v); + } + + protected int allocateConstantPoolFloat(float v) { + return cw.addCPFloat(v); + } + + protected int allocateConstantPoolLong(long v) { + return cw.addCPLong(v); + } + + protected int allocateConstantPoolDouble(double v) { + return cw.addCPDouble(v); + } + + protected int allocateConstantPoolString(String v) { + return cw.addCPString(v); + } + + protected int allocateConstantPoolClassType(String c) { + return cw.addCPClass(convertTypeToClass(c)); + } + + /** + * Convert a JVM type to the internal JVM class name (e.g., Ljava/lang/Object; + * to java/lang/Object) + */ + public static String convertTypeToClass(String s) { + if (s.length() > 0 && s.charAt(0) == 'L') { + return s.substring(1, s.length() - 1); + } else { + return s; + } + } + + protected int allocateConstantPoolField(String c, String name, String type) { + return cw.addCPFieldRef(convertTypeToClass(c), name, type); + } + + protected int allocateConstantPoolMethod(String c, String name, String sig) { + return cw.addCPMethodRef(convertTypeToClass(c), name, sig); + } + + protected int allocateConstantPoolInterfaceMethod(String c, String name, String sig) { + return cw.addCPInterfaceMethodRef(convertTypeToClass(c), name, sig); + } + + protected String createHelperMethod(boolean isStatic, String sig) { + long r = Math.abs((new Random()).nextLong()); + String name = "_helper_" + r; + + return name; + } +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/shrikeCT/CTDecoder.java b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/shrikeCT/CTDecoder.java new file mode 100644 index 000000000..46406128c --- /dev/null +++ b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/shrikeCT/CTDecoder.java @@ -0,0 +1,149 @@ +/******************************************************************************* + * 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.shrikeBT.shrikeCT; + +import com.ibm.wala.shrikeBT.ConstantPoolReader; +import com.ibm.wala.shrikeBT.Decoder; +import com.ibm.wala.shrikeCT.ClassReader; +import com.ibm.wala.shrikeCT.CodeReader; +import com.ibm.wala.shrikeCT.ConstantPoolParser; +import com.ibm.wala.shrikeCT.InvalidClassFileException; + +/** + * This class decodes Java bytecodes into ShrikeBT code using a ShrikeCT class + * reader. + */ +final public class CTDecoder extends Decoder { + + /** + * Decode the code resource 'r'. + */ + public CTDecoder(CodeReader r) { + this(r, makeConstantPoolReader(r.getClassReader())); + } + + /** + * Decode the code resource 'r' using the predeclared constant pool reader + * 'cpr' (obtained by makeConstantPoolReader below). + */ + public CTDecoder(CodeReader r, ConstantPoolReader cpr) { + super(r.getBytecode(), r.getRawHandlers(), cpr); + } + + /** + * Convert the internal JVM class name to a JVM type name (e.g., + * java/lang/Object to Ljava/lang/Object;). + */ + public static String convertClassToType(String s) { + if (s.length() > 0 && s.charAt(0) != '[') { + return "L" + s + ";"; + } else { + return s; + } + } + + /** + * Build a ConstantPoolReader implementation to read the constant pool from + * 'cr'. + */ + public static ConstantPoolReader makeConstantPoolReader(ClassReader cr) { + return new CPReader(cr.getCP()); + } + + final static class CPReader extends ConstantPoolReader { + private ConstantPoolParser cp; + + CPReader(ConstantPoolParser cp) { + this.cp = cp; + } + + public int getConstantPoolItemType(int index) { + return cp.getItemType(index); + } + + private Error convertToError(InvalidClassFileException e) { + e.printStackTrace(); + return new Error("Invalid class file: " + e.getMessage()); + } + + public int getConstantPoolInteger(int index) { + try { + return cp.getCPInt(index); + } catch (InvalidClassFileException e) { + throw convertToError(e); + } + } + + public float getConstantPoolFloat(int index) { + try { + return cp.getCPFloat(index); + } catch (InvalidClassFileException e) { + throw convertToError(e); + } + } + + public long getConstantPoolLong(int index) { + try { + return cp.getCPLong(index); + } catch (InvalidClassFileException e) { + throw convertToError(e); + } + } + + public double getConstantPoolDouble(int index) { + try { + return cp.getCPDouble(index); + } catch (InvalidClassFileException e) { + throw convertToError(e); + } + } + + public String getConstantPoolString(int index) { + try { + return cp.getCPString(index); + } catch (InvalidClassFileException e) { + throw convertToError(e); + } + } + + public String getConstantPoolClassType(int index) { + try { + return convertClassToType(cp.getCPClass(index)); + } catch (InvalidClassFileException e) { + throw convertToError(e); + } + } + + public String getConstantPoolMemberClassType(int index) { + try { + return convertClassToType(cp.getCPRefClass(index)); + } catch (InvalidClassFileException e) { + throw convertToError(e); + } + } + + public String getConstantPoolMemberName(int index) { + try { + return cp.getCPRefName(index); + } catch (InvalidClassFileException e) { + throw convertToError(e); + } + } + + public String getConstantPoolMemberType(int index) { + try { + return cp.getCPRefType(index); + } catch (InvalidClassFileException e) { + throw convertToError(e); + } + } + } +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/shrikeCT/CTUtils.java b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/shrikeCT/CTUtils.java new file mode 100644 index 000000000..6f6e430dc --- /dev/null +++ b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/shrikeCT/CTUtils.java @@ -0,0 +1,34 @@ +/******************************************************************************* + * 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.shrikeBT.shrikeCT; + +import com.ibm.wala.shrikeBT.Constants; +import com.ibm.wala.shrikeBT.analysis.ClassHierarchyStore; +import com.ibm.wala.shrikeCT.ClassReader; +import com.ibm.wala.shrikeCT.InvalidClassFileException; + +/** + * This is a dumping ground for useful functions that manipulate class info. + * + * @author roca@us.ibm.com + */ +public class CTUtils { + public static void addClassToHierarchy(ClassHierarchyStore store, ClassReader cr) throws InvalidClassFileException { + String[] superInterfaces = new String[cr.getInterfaceCount()]; + for (int i = 0; i < superInterfaces.length; i++) { + superInterfaces[i] = CTDecoder.convertClassToType(cr.getInterfaceName(i)); + } + String superName = cr.getSuperName(); + store.setClassInfo(CTDecoder.convertClassToType(cr.getName()), (cr.getAccessFlags() & Constants.ACC_INTERFACE) != 0, (cr + .getAccessFlags() & Constants.ACC_FINAL) != 0, superName != null ? CTDecoder.convertClassToType(superName) : null, + superInterfaces); + } +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/shrikeCT/ClassInstrumenter.java b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/shrikeCT/ClassInstrumenter.java new file mode 100644 index 000000000..e6e56302a --- /dev/null +++ b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/shrikeCT/ClassInstrumenter.java @@ -0,0 +1,523 @@ +/******************************************************************************* + * 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.shrikeBT.shrikeCT; + +import java.util.ArrayList; +import java.util.Arrays; + +import com.ibm.wala.shrikeBT.Compiler; +import com.ibm.wala.shrikeBT.ConstantPoolReader; +import com.ibm.wala.shrikeBT.Constants; +import com.ibm.wala.shrikeBT.ExceptionHandler; +import com.ibm.wala.shrikeBT.Instruction; +import com.ibm.wala.shrikeBT.MethodData; +import com.ibm.wala.shrikeBT.ReturnInstruction; +import com.ibm.wala.shrikeBT.Util; +import com.ibm.wala.shrikeBT.Decoder.InvalidBytecodeException; +import com.ibm.wala.shrikeCT.ClassConstants; +import com.ibm.wala.shrikeCT.ClassReader; +import com.ibm.wala.shrikeCT.ClassWriter; +import com.ibm.wala.shrikeCT.CodeReader; +import com.ibm.wala.shrikeCT.CodeWriter; +import com.ibm.wala.shrikeCT.InvalidClassFileException; +import com.ibm.wala.shrikeCT.LineNumberTableReader; +import com.ibm.wala.shrikeCT.LineNumberTableWriter; +import com.ibm.wala.shrikeCT.LocalVariableTableReader; +import com.ibm.wala.shrikeCT.LocalVariableTableWriter; +import com.ibm.wala.shrikeCT.ClassWriter.Element; + +/** + * This class provides a convenient way to instrument every method in a class. + * It assumes you are using ShrikeCT to read and write classes. It's stateful; + * initially every method is set to the original code read from the class, but + * you can then go in and modify the methods. + */ +final public class ClassInstrumenter { + private boolean[] deletedMethods; + private MethodData[] methods; + private CodeReader[] oldCode; + private ClassReader cr; + private ConstantPoolReader cpr; + private boolean createFakeLineNumbers = false; + private int fakeLineOffset; + + /** + * Create a class instrumenter from raw bytes. + */ + public ClassInstrumenter(byte[] bytes) throws InvalidClassFileException { + this(new ClassReader(bytes)); + } + + /** + * Calling this means that methods without line numbers get fake line numbers + * added: each bytecode instruction is treated as at line 'offset' + the + * offset of the instruction. + */ + public void enableFakeLineNumbers(int offset) { + createFakeLineNumbers = true; + fakeLineOffset = offset; + } + + /** + * Create a class instrumenter from a preinitialized class reader. + */ + public ClassInstrumenter(ClassReader cr) throws InvalidClassFileException { + this.cr = cr; + methods = new MethodData[cr.getMethodCount()]; + oldCode = new CodeReader[methods.length]; + cpr = CTDecoder.makeConstantPoolReader(cr); + deletedMethods = new boolean[methods.length]; + } + + /** + * @return the reader for the class + */ + public ClassReader getReader() { + return cr; + } + + /** + * Implement this interface to instrument every method of a class using + * visitMethods() below. + */ + public static interface MethodExaminer { + /** + * Do something to the method. + */ + public void examineCode(MethodData data); + } + + private void prepareMethod(int i) throws InvalidClassFileException { + if (deletedMethods[i]) { + methods[i] = null; + } else if (methods[i] == null) { + ClassReader.AttrIterator iter = new ClassReader.AttrIterator(); + cr.initMethodAttributeIterator(i, iter); + for (; iter.isValid(); iter.advance()) { + if (iter.getName().equals("Code")) { + CodeReader code = new CodeReader(iter); + CTDecoder d = new CTDecoder(code, cpr); + try { + d.decode(); + } catch (InvalidBytecodeException e) { + throw new InvalidClassFileException(code.getRawOffset(), e.getMessage()); + } + MethodData md = new MethodData(d, cr.getMethodAccessFlags(i), CTDecoder.convertClassToType(cr.getName()), cr + .getMethodName(i), cr.getMethodType(i)); + methods[i] = md; + oldCode[i] = code; + return; + } + } + } + } + + /** + * Indicate that the method should be deleted from the class. + * + * @param i + * the index of the method to delete + */ + public void deleteMethod(int i) { + deletedMethods[i] = true; + } + + private final static ExceptionHandler[] noHandlers = new ExceptionHandler[0]; + + //Xiangyu + //create a empty method body and then user can apply patches later on + public MethodData createEmptyMethodData(String name, String sig, int access) { + //Instruction[] instructions=new Instruction[0]; + Instruction[] instructions = new Instruction[1]; + instructions[0] = ReturnInstruction.make(Constants.TYPE_void); + ExceptionHandler[][] handlers = new ExceptionHandler[instructions.length][]; + Arrays.fill(handlers, noHandlers); + int[] i2b = new int[instructions.length]; + for (int i = 0; i < i2b.length; i++) { + i2b[i] = i; + } + MethodData md = null; + try { + md = new MethodData(access, Util.makeType(cr.getName()), name, sig, instructions, handlers, i2b); + + } catch (InvalidClassFileException ex) { + ex.printStackTrace(); + } + return md; + + } + + /** + * Xiangyu + * + * + */ + public void newMethod(String name, String sig, ArrayList instructions, int access, ClassWriter classWriter, + ClassWriter.Element rawLines) { + Instruction[] ins = (Instruction[]) instructions.toArray(new Instruction[instructions.size()]); + ExceptionHandler[][] handlers = new ExceptionHandler[ins.length][]; + Arrays.fill(handlers, noHandlers); + int[] i2b = new int[ins.length]; + for (int i = 0; i < i2b.length; i++) { + i2b[i] = i; + } + MethodData md = null; + try { + md = new MethodData(access, Util.makeType(cr.getName()), name, sig, ins, handlers, i2b); + } catch (InvalidClassFileException ex) { + ex.printStackTrace(); + } + CTCompiler compiler = new CTCompiler(classWriter, md); + compiler.compile(); + CTCompiler.Output output = compiler.getOutput(); + CodeWriter code = new CodeWriter(classWriter); + code.setMaxStack(output.getMaxStack()); + code.setMaxLocals(output.getMaxLocals()); + code.setCode(output.getCode()); + code.setRawHandlers(output.getRawHandlers()); + + LineNumberTableWriter lines = null; + //I guess it is the line numbers in the java files. + if (rawLines == null) { + // add fake line numbers: just map each bytecode instruction to its own + // 'line' + int[] newLineMap = new int[instructions.size()]; + for (int i = 0; i < newLineMap.length; i++) { + newLineMap[i] = i; + } + int[] rawTable = LineNumberTableWriter.makeRawTable(newLineMap); + lines = new LineNumberTableWriter(classWriter); + lines.setRawTable(rawTable); + } + code.setAttributes(new ClassWriter.Element[] { rawLines == null ? lines : rawLines }); + Element[] elements = { code }; + classWriter.addMethod(access, name, sig, elements); + } + + public void newMethod(MethodData md, ClassWriter classWriter, ClassWriter.Element rawLines) { + CTCompiler compiler = new CTCompiler(classWriter, md); + compiler.compile(); + CTCompiler.Output output = compiler.getOutput(); + CodeWriter code = new CodeWriter(classWriter); + code.setMaxStack(output.getMaxStack()); + code.setMaxLocals(output.getMaxLocals()); + code.setCode(output.getCode()); + code.setRawHandlers(output.getRawHandlers()); + + LineNumberTableWriter lines = null; + //I guess it is the line numbers in the java files. + if (rawLines == null) { + // add fake line numbers: just map each bytecode instruction to its own + // 'line' + + //NOTE:Should not use md.getInstructions().length, because the + //the length of the created code can be smaller than the md's instruction + // length + + //WRONG: int[] newLineMap = new int[md.getInstructions().length]; + int[] newLineMap = new int[code.getCodeLength()]; + for (int i = 0; i < newLineMap.length; i++) { + newLineMap[i] = i; + } + int[] rawTable = LineNumberTableWriter.makeRawTable(newLineMap); + lines = new LineNumberTableWriter(classWriter); + lines.setRawTable(rawTable); + } + code.setAttributes(new ClassWriter.Element[] { rawLines == null ? lines : rawLines }); + Element[] elements = { code }; + //System.out.println("Name:"+md.getName()+" Sig:"+md.getSignature()); + classWriter.addMethod(md.getAccess(), md.getName(), md.getSignature(), elements); + } + + /** + * Do something to every method in the class. This will visit all methods, + * including those already marked for deletion. + * + * @param me + * the visitor to apply to each method + */ + public void visitMethods(MethodExaminer me) throws InvalidClassFileException { + for (int i = 0; i < methods.length; i++) { + prepareMethod(i); + if (methods[i] != null) { + me.examineCode(methods[i]); + } + } + } + + /** + * Get the current state of method i. This can be edited using a MethodEditor. + * + * @param i + * the index of the method to inspect + */ + public MethodData visitMethod(int i) throws InvalidClassFileException { + prepareMethod(i); + return methods[i]; + } + + /** + * Get the original code resource for the method. + * + * @param i + * the index of the method to inspect + */ + public CodeReader getMethodCode(int i) throws InvalidClassFileException { + prepareMethod(i); + return oldCode[i]; + } + + /** + * Reset method i back to the code from the original class, and "undelete" it + * if it was marked for deletion. + * + * @param i + * the index of the method to reset + */ + public void resetMethod(int i) { + deletedMethods[i] = false; + methods[i] = null; + } + + /** + * Replace the code for method i with new code. This also "undeletes" the + * method if it was marked for deletion. + * + * @param i + * the index of the method to replace + */ + public void replaceMethod(int i, MethodData md) { + deletedMethods[i] = false; + methods[i] = md; + oldCode[i] = null; + md.setHasChanged(); + } + + /** + * Check whether any methods in the class have actually been changed. + */ + public boolean isChanged() { + for (int i = 0; i < methods.length; i++) { + if (deletedMethods[i] || (methods[i] != null && methods[i].getHasChanged())) { + return true; + } + } + return false; + } + + /** + * Create a class which is a copy of the original class but with the new + * method code. We return the ClassWriter used, so more methods and fields + * (and other changes) can still be added. + * + * We fix up any debug information to be consistent with the changes to the + * code. + */ + public ClassWriter emitClass() throws InvalidClassFileException { + ClassWriter w = new ClassWriter(); + emitClassInto(w); + return w; + } + + /** + * Copy the contents of the old class, plus any method modifications, into a + * new ClassWriter. The ClassWriter must be empty! + * + * @param w + * the classwriter to copy into. + */ + private void emitClassInto(ClassWriter w) throws InvalidClassFileException { + w.setMajorVersion(cr.getMajorVersion()); + w.setMinorVersion(cr.getMinorVersion()); + w.setRawCP(cr.getCP(), false); + w.setAccessFlags(cr.getAccessFlags()); + w.setNameIndex(cr.getNameIndex()); + w.setSuperNameIndex(cr.getSuperNameIndex()); + w.setInterfaceNameIndices(cr.getInterfaceNameIndices()); + + int fieldCount = cr.getFieldCount(); + for (int i = 0; i < fieldCount; i++) { + w.addRawField(new ClassWriter.RawElement(cr.getBytes(), cr.getFieldRawOffset(i), cr.getFieldRawSize(i))); + } + + for (int i = 0; i < methods.length; i++) { + MethodData md = methods[i]; + if (!deletedMethods[i]) { + if (md == null || !md.getHasChanged()) { + w.addRawMethod(new ClassWriter.RawElement(cr.getBytes(), cr.getMethodRawOffset(i), cr.getMethodRawSize(i))); + } else { + CTCompiler comp = new CTCompiler(w, md); + comp.setPresetConstants(cpr); + + try { + comp.compile(); + } catch (Error ex) { + ex.printStackTrace(); + throw new Error("Error compiling method " + md + ": " + ex.getMessage()); + } catch (Exception ex) { + ex.printStackTrace(); + throw new Error("Error compiling method " + md + ": " + ex.getMessage()); + } + + CodeReader oc = oldCode[i]; + int flags = cr.getMethodAccessFlags(i); + // we're not installing a native method here + flags &= ~ClassConstants.ACC_NATIVE; + w.addMethod(flags, cr.getMethodNameIndex(i), cr.getMethodTypeIndex(i), makeMethodAttributes(i, w, oc, comp.getOutput())); + Compiler.Output[] aux = comp.getAuxiliaryMethods(); + if (aux != null) { + for (int j = 0; j < aux.length; j++) { + Compiler.Output a = aux[j]; + w.addMethod(a.getAccessFlags(), a.getMethodName(), a.getMethodSignature(), makeMethodAttributes(i, w, oc, a)); + } + } + } + } + } + + ClassReader.AttrIterator iter = new ClassReader.AttrIterator(); + cr.initClassAttributeIterator(iter); + for (; iter.isValid(); iter.advance()) { + w.addClassAttribute(new ClassWriter.RawElement(cr.getBytes(), iter.getRawOffset(), iter.getRawSize())); + } + } + + private static CodeWriter makeNewCode(ClassWriter w, Compiler.Output output) { + CodeWriter code = new CodeWriter(w); + code.setMaxStack(output.getMaxStack()); + code.setMaxLocals(output.getMaxLocals()); + code.setCode(output.getCode()); + code.setRawHandlers(output.getRawHandlers()); + return code; + } + + private LineNumberTableWriter makeNewLines(ClassWriter w, CodeReader oldCode, Compiler.Output output) + throws InvalidClassFileException { + int[] newLineMap = null; + int[] oldLineMap = LineNumberTableReader.makeBytecodeToSourceMap(oldCode); + if (oldLineMap != null) { + // Map the old line number map onto the new bytecodes + int[] newToOldMap = output.getNewBytecodesToOldBytecodes(); + newLineMap = new int[newToOldMap.length]; + for (int i = 0; i < newToOldMap.length; i++) { + int old = newToOldMap[i]; + if (old >= 0) { + newLineMap[i] = oldLineMap[old]; + } + } + } else if (createFakeLineNumbers) { + newLineMap = new int[output.getCode().length]; + for (int i = 0; i < newLineMap.length; i++) { + newLineMap[i] = i + fakeLineOffset; + } + } else { + return null; + } + + // Now compress it into the JVM form + int[] rawTable = LineNumberTableWriter.makeRawTable(newLineMap); + if (rawTable == null || rawTable.length == 0) { + return null; + } else { + LineNumberTableWriter lines = new LineNumberTableWriter(w); + lines.setRawTable(rawTable); + return lines; + } + } + + private static LocalVariableTableWriter makeNewLocals(ClassWriter w, CodeReader oldCode, Compiler.Output output) + throws InvalidClassFileException { + int[][] oldMap = LocalVariableTableReader.makeVarMap(oldCode); + if (oldMap != null) { + // Map the old map onto the new bytecodes + int[] newToOldMap = output.getNewBytecodesToOldBytecodes(); + int[][] newMap = new int[newToOldMap.length][]; + int[] lastLocals = null; + for (int i = 0; i < newToOldMap.length; i++) { + int old = newToOldMap[i]; + if (old >= 0) { + newMap[i] = oldMap[old]; + lastLocals = newMap[i]; + } else { + newMap[i] = lastLocals; + } + } + + int[] rawTable = LocalVariableTableWriter.makeRawTable(newMap); + if (rawTable == null || rawTable.length == 0) { + return null; + } else { + LocalVariableTableWriter locals = new LocalVariableTableWriter(w); + locals.setRawTable(rawTable); + return locals; + } + } else { + return null; + } + } + + private ClassWriter.Element[] makeMethodAttributes(int m, ClassWriter w, CodeReader oldCode, Compiler.Output output) + throws InvalidClassFileException { + CodeWriter code = makeNewCode(w, output); + + int codeAttrCount = 0; + LineNumberTableWriter lines = null; + LocalVariableTableWriter locals = null; + if (oldCode != null) { + lines = makeNewLines(w, oldCode, output); + if (lines != null) { + codeAttrCount++; + } + locals = makeNewLocals(w, oldCode, output); + if (locals != null) { + codeAttrCount++; + } + } + ClassWriter.Element[] codeAttributes = new ClassWriter.Element[codeAttrCount]; + int codeAttrIndex = 0; + if (lines != null) { + codeAttributes[0] = lines; + codeAttrIndex++; + } + if (locals != null) { + codeAttributes[codeAttrIndex] = locals; + } + code.setAttributes(codeAttributes); + + ClassReader.AttrIterator iter = new ClassReader.AttrIterator(); + cr.initMethodAttributeIterator(m, iter); + int methodAttrCount = iter.getRemainingAttributesCount(); + if (oldCode == null) { + methodAttrCount++; + } + ClassWriter.Element[] methodAttributes = new ClassWriter.Element[methodAttrCount]; + for (int i = 0; iter.isValid(); iter.advance()) { + if (iter.getName().equals("Code")) { + methodAttributes[i] = code; + code = null; + if (oldCode == null) { + throw new Error("No old code provided, but Code attribute found"); + } + } else { + methodAttributes[i] = new ClassWriter.RawElement(cr.getBytes(), iter.getRawOffset(), iter.getRawSize()); + } + i++; + } + if (oldCode == null) { + if (code == null) { + throw new Error("Old code not provided but existing code was found and replaced"); + } + methodAttributes[methodAttrCount - 1] = code; + } + + return methodAttributes; + } +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/shrikeCT/OfflineInstrumenter.java b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/shrikeCT/OfflineInstrumenter.java new file mode 100644 index 000000000..7e00eec42 --- /dev/null +++ b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/shrikeCT/OfflineInstrumenter.java @@ -0,0 +1,90 @@ +/******************************************************************************* + * 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.shrikeBT.shrikeCT; + +import java.io.BufferedInputStream; +import java.io.IOException; +import java.io.OutputStream; + +import com.ibm.wala.shrikeBT.Util; +import com.ibm.wala.shrikeBT.tools.OfflineInstrumenterBase; +import com.ibm.wala.shrikeCT.ClassWriter; +import com.ibm.wala.shrikeCT.InvalidClassFileException; + +/** + * This class provides a convenient way to iterate through a collection of Java + * classes and instrument their code. This is just a specialization of + * OfflineInstrumenterBase to use the shrikeCT functionality. + */ +final public class OfflineInstrumenter extends OfflineInstrumenterBase { + /** + * Create an empty collection of classes to instrument. + */ + public OfflineInstrumenter() { + } + + protected Object makeClassFromStream(BufferedInputStream s) throws IOException { + byte[] bytes = new byte[s.available()]; + Util.readFully(s, bytes); + try { + return new ClassInstrumenter(bytes); + } catch (InvalidClassFileException e) { + throw new IOException("Class is invalid: " + e.getMessage()); + } + } + + protected String getClassName(Object cl) { + try { + return ((ClassInstrumenter) cl).getReader().getName().replace('/', '.'); + } catch (InvalidClassFileException e) { + return null; + } + } + + protected void writeClassTo(Object cl, Object mods, OutputStream s) throws IOException { + ClassInstrumenter ci = (ClassInstrumenter) cl; + ClassWriter cw = (ClassWriter) mods; + if (cw == null) { + s.write(ci.getReader().getBytes()); + } else { + s.write(cw.makeBytes()); + } + } + + /** + * Get the next class to be instrumented. + */ + public ClassInstrumenter nextClass() throws IOException { + return (ClassInstrumenter) internalNextClass(); + } + + /** + * Update the original class with some method changes. 'code' should be the + * result of out.emitClass(). You can add new fields and methods to 'code' (or + * make other changes) before calling this method. + */ + public void outputModifiedClass(ClassInstrumenter out, ClassWriter code) throws IOException { + internalOutputModifiedClass(out, code); + } + + /** + * Update the original class with some method changes. This method calls + * out.emitClass() for you. + */ + public void outputModifiedClass(ClassInstrumenter out) throws IOException { + try { + internalOutputModifiedClass(out, out.emitClass()); + } catch (InvalidClassFileException e) { + e.printStackTrace(); + throw new IOException("Invalid class file"); + } + } +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/shrikeCT/tools/AddSerialVersion.java b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/shrikeCT/tools/AddSerialVersion.java new file mode 100644 index 000000000..dc1c815f7 --- /dev/null +++ b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/shrikeCT/tools/AddSerialVersion.java @@ -0,0 +1,187 @@ +/******************************************************************************* + * 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.shrikeBT.shrikeCT.tools; + +import java.io.DataOutputStream; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.OutputStream; +import java.security.DigestOutputStream; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.util.Arrays; +import java.util.Comparator; + +import com.ibm.wala.shrikeBT.Util; +import com.ibm.wala.shrikeCT.ClassReader; +import com.ibm.wala.shrikeCT.ClassWriter; +import com.ibm.wala.shrikeCT.ConstantValueWriter; +import com.ibm.wala.shrikeCT.InvalidClassFileException; + +public class AddSerialVersion { + /** + * This method computes the serialVersionUID for class r (if there isn't one + * already) and adds the field to the classwriter w. + * + * When run as a program, just takes a list of class files as command line + * arguments and computes their serialVersionUIDs. + */ + public static void addSerialVersionUID(ClassReader r, ClassWriter w) throws InvalidClassFileException { + int numFields = r.getFieldCount(); + for (int i = 0; i < numFields; i++) { + if (r.getFieldName(i).equals("serialVersionUID")) { + return; // already has a serialVersionUID + } + } + + long UID = computeSerialVersionUID(r); + w.addField(ClassReader.ACC_PUBLIC | ClassReader.ACC_STATIC | ClassReader.ACC_FINAL, "serialVersionUID", "J", + new ClassWriter.Element[] { new ConstantValueWriter(w, UID) }); + } + + /** + * This class implements a stream that just discards everything written to it. + */ + public static final class SinkOutputStream extends OutputStream { + public void write(int b) { + } + + public void write(byte[] b) { + } + + public void write(byte[] b, int off, int len) { + } + } + + /** + * This method computes the serialVersionUID for class r. See the + * specification at + * http://java.sun.com/j2se/1.4.2/docs/guide/serialization/spec/class.html + */ + public static long computeSerialVersionUID(final ClassReader r) throws InvalidClassFileException { + MessageDigest digest; + try { + digest = MessageDigest.getInstance("SHA"); + } catch (NoSuchAlgorithmException e) { + throw new Error("SHA algorithm not supported: " + e.getMessage()); + } + SinkOutputStream sink = new SinkOutputStream(); + DataOutputStream out = new DataOutputStream(new DigestOutputStream(sink, digest)); + + try { + // step 1 + out.writeUTF(r.getName()); + // step 2 + out.writeInt(r.getAccessFlags()); + + // step 3 + String[] interfaces = r.getInterfaceNames(); + Arrays.sort(interfaces); + for (int i = 0; i < interfaces.length; i++) { + out.writeUTF(interfaces[i]); + } + + // step 4 + Integer[] fields = new Integer[r.getFieldCount()]; + final String[] fieldNames = new String[fields.length]; + int fieldCount = 0; + for (int f = 0; f < fields.length; f++) { + int flags = r.getFieldAccessFlags(f); + if ((flags & ClassReader.ACC_PRIVATE) == 0 || (flags & (ClassReader.ACC_STATIC | ClassReader.ACC_TRANSIENT)) == 0) { + fields[fieldCount] = new Integer(f); + fieldNames[f] = r.getFieldName(f); + fieldCount++; + } + } + Arrays.sort(fields, 0, fieldCount, new Comparator() { + public int compare(Integer o1, Integer o2) { + String name1 = fieldNames[((Integer) o1).intValue()]; + String name2 = fieldNames[((Integer) o2).intValue()]; + return name1.compareTo(name2); + } + }); + for (int i = 0; i < fieldCount; i++) { + int f = ((Integer) fields[i]).intValue(); + out.writeUTF(fieldNames[f]); + out.writeInt(r.getFieldAccessFlags(f)); + out.writeUTF(r.getFieldType(f)); + } + + // steps 5, 6 and 7 + Integer[] methods = new Integer[r.getMethodCount()]; + final int[] methodKinds = new int[methods.length]; + final String[] methodSigs = new String[methods.length]; + int methodCount = 0; + for (int m = 0; m < methodSigs.length; m++) { + String name = r.getMethodName(m); + int flags = r.getMethodAccessFlags(m); + if (name.equals("") || (flags & ClassReader.ACC_PRIVATE) == 0) { + methods[methodCount] = new Integer(m); + methodSigs[m] = name + r.getMethodType(m); + if (name.equals("")) { + methodKinds[m] = 0; + } else if (name.equals("")) { + methodKinds[m] = 1; + } else { + methodKinds[m] = 2; + } + methodCount++; + } + } + Arrays.sort(methods, 0, methodCount, new Comparator() { + public int compare(Integer o1, Integer o2) { + int m1 = ((Integer) o1).intValue(); + int m2 = ((Integer) o2).intValue(); + if (methodKinds[m1] != methodKinds[m2]) { + return methodKinds[m1] - methodKinds[m2]; + } + String name1 = methodSigs[m1]; + String name2 = methodSigs[m2]; + return name1.compareTo(name2); + } + }); + for (int i = 0; i < methodCount; i++) { + int m = ((Integer) methods[i]).intValue(); + out.writeUTF(r.getMethodName(m)); + out.writeInt(r.getMethodAccessFlags(m)); + out.writeUTF(r.getMethodType(m)); + } + } catch (IOException e1) { + throw new Error("Unexpected IOException: " + e1.getMessage()); + } finally { + try { + out.close(); + } catch (IOException e2) { + } + } + + byte[] hash = digest.digest(); + return (hash[0] & 0xFF) | (hash[1] & 0xFF) << 8 | (hash[2] & 0xFF) << 16 | hash[3] << 24 | (hash[4] & 0xFF) << 32 + | (hash[5] & 0xFF) << 40 | (hash[6] & 0xFF) << 48 | (hash[7] & 0xFF) << 56; + } + + public static void main(String[] args) { + for (int i = 0; i < args.length; i++) { + try { + byte[] data = Util.readFully(new FileInputStream(args[i])); + ClassReader r = new ClassReader(data); + System.out.println(Util.makeClass(r.getName()) + ": serialVersionUID = " + computeSerialVersionUID(r)); + } catch (FileNotFoundException e) { + System.err.println("File not found: " + args[i]); + } catch (IOException e) { + System.err.println("Error reading file: " + args[i]); + } catch (InvalidClassFileException e) { + System.err.println("Invalid class file: " + args[i]); + } + } + } +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/shrikeCT/tools/BatchVerifier.java b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/shrikeCT/tools/BatchVerifier.java new file mode 100644 index 000000000..8b36101b4 --- /dev/null +++ b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/shrikeCT/tools/BatchVerifier.java @@ -0,0 +1,128 @@ +/******************************************************************************* + * 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.shrikeBT.shrikeCT.tools; + +import java.io.BufferedWriter; +import java.io.FileWriter; +import java.io.PrintWriter; + +import com.ibm.wala.shrikeBT.Decoder; +import com.ibm.wala.shrikeBT.Disassembler; +import com.ibm.wala.shrikeBT.MethodData; +import com.ibm.wala.shrikeBT.analysis.ClassHierarchyStore; +import com.ibm.wala.shrikeBT.analysis.Verifier; +import com.ibm.wala.shrikeBT.analysis.Analyzer.FailureException; +import com.ibm.wala.shrikeBT.shrikeCT.CTDecoder; +import com.ibm.wala.shrikeBT.shrikeCT.CTUtils; +import com.ibm.wala.shrikeBT.shrikeCT.ClassInstrumenter; +import com.ibm.wala.shrikeBT.shrikeCT.OfflineInstrumenter; +import com.ibm.wala.shrikeCT.ClassReader; +import com.ibm.wala.shrikeCT.CodeReader; +import com.ibm.wala.shrikeCT.InvalidClassFileException; + +/** + * This is a demo class. + * + * Class files are taken as input arguments (or if there are none, from standard + * input). The methods in those files are instrumented: we insert a + * System.err.println() at ever method call, and a System.err.println() at every + * method entry. + * + * In Unix, I run it like this: java -cp ~/dev/shrike/shrike + * com.ibm.wala.shrikeBT.shrikeCT.tools.BatchVerifier test.jar -o output.jar + * + * The instrumented classes are placed in the directory "output" under the + * current directory. Disassembled code is written to the file "report" under + * the current directory. + */ +public class BatchVerifier { + private static boolean disasm = false; + private static ClassHierarchyStore store = new ClassHierarchyStore(); + private static int errors = 0; + + public static void main(String[] args) throws Exception { + OfflineInstrumenter oi = new OfflineInstrumenter(); + args = oi.parseStandardArgs(args); + + for (int i = 0; i < args.length; i++) { + if (args[i].equals("-d")) { + disasm = true; + } + } + + PrintWriter w = new PrintWriter(new BufferedWriter(new FileWriter("report", false))); + + oi.beginTraversal(); + ClassInstrumenter ci; + while ((ci = oi.nextClass()) != null) { + ClassReader cr = ci.getReader(); + CTUtils.addClassToHierarchy(store, cr); + } + + oi.beginTraversal(); + while ((ci = oi.nextClass()) != null) { + doClass(ci.getReader(), w); + } + + oi.close(); + + if (errors > 0) { + System.err.println(errors + " error" + (errors > 1 ? "s" : "") + " detected"); + } + } + + private static void doClass(final ClassReader cr, PrintWriter w) throws Exception { + int methodCount = cr.getMethodCount(); + w.write("Verifying " + cr.getName() + "\n"); + w.flush(); + + ClassReader.AttrIterator iter = new ClassReader.AttrIterator(); + + for (int i = 0; i < methodCount; i++) { + cr.initMethodAttributeIterator(i, iter); + for (; iter.isValid(); iter.advance()) { + if (iter.getName().equals("Code")) { + w.write("Verifying " + cr.getName() + "." + cr.getMethodName(i) + " " + cr.getMethodType(i) + ":\n"); + w.flush(); + + CodeReader code = new CodeReader(iter); + CTDecoder d = new CTDecoder(code); + try { + d.decode(); + } catch (Decoder.InvalidBytecodeException e) { + throw new InvalidClassFileException(code.getRawOffset(), e.getMessage()); + } + MethodData md = new MethodData(d, cr.getMethodAccessFlags(i), CTDecoder.convertClassToType(cr.getName()), cr + .getMethodName(i), cr.getMethodType(i)); + + if (disasm) { + w.write("ShrikeBT code:\n"); + (new Disassembler(md)).disassembleTo(w); + w.flush(); + } + + Verifier v = new Verifier(md); + try { + v.verify(); + } catch (FailureException e) { + w.println("ERROR: VERIFICATION FAILED"); + e.printStackTrace(w); + e.printPath(w); + errors++; + w.flush(); + } + + break; + } + } + } + } +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/shrikeCT/tools/ClassPrinter.java b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/shrikeCT/tools/ClassPrinter.java new file mode 100644 index 000000000..b145d9976 --- /dev/null +++ b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/shrikeCT/tools/ClassPrinter.java @@ -0,0 +1,382 @@ +/******************************************************************************* + * 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.shrikeBT.shrikeCT.tools; + +import java.io.BufferedWriter; +import java.io.IOException; +import java.io.OutputStreamWriter; +import java.io.PrintWriter; +import java.lang.reflect.Field; + +import com.ibm.wala.shrikeBT.Constants; +import com.ibm.wala.shrikeBT.Disassembler; +import com.ibm.wala.shrikeBT.Decoder.InvalidBytecodeException; +import com.ibm.wala.shrikeBT.shrikeCT.CTDecoder; +import com.ibm.wala.shrikeBT.shrikeCT.ClassInstrumenter; +import com.ibm.wala.shrikeBT.shrikeCT.OfflineInstrumenter; +import com.ibm.wala.shrikeCT.ClassConstants; +import com.ibm.wala.shrikeCT.ClassReader; +import com.ibm.wala.shrikeCT.CodeReader; +import com.ibm.wala.shrikeCT.ConstantPoolParser; +import com.ibm.wala.shrikeCT.ConstantValueReader; +import com.ibm.wala.shrikeCT.InvalidClassFileException; +import com.ibm.wala.shrikeCT.LineNumberTableReader; +import com.ibm.wala.shrikeCT.LocalVariableTableReader; +import com.ibm.wala.shrikeCT.SourceFileReader; + +/** + * This class prints the contents of a class file. It's like an alternative to + * javap that shows more information. + * + * In Unix I run it like this: java -cp ~/dev/shrike/shrike + * com.ibm.wala.shrikeBT.shrikeCT.tools.ClassPrinter test.jar This will print the + * contents of every class in the JAR file. + */ +public class ClassPrinter { + private PrintWriter w; + private boolean printLineNumberInfo = true; + private boolean printConstantPool = true; + + /** + * Get ready to print a class to the given output stream. + */ + public ClassPrinter(PrintWriter w) { + this.w = w; + } + + /** + * Controls whether to print line number information. The default is 'true'. + */ + public void setPrintLineNumberInfo(boolean b) { + printLineNumberInfo = b; + } + + /** + * Controls whether to print all the constant pool entries. The default is + * 'true'. + */ + public void setPrintConstantPool(boolean b) { + printConstantPool = b; + } + + public static void main(String[] args) throws Exception { + OfflineInstrumenter oi = new OfflineInstrumenter(); + args = oi.parseStandardArgs(args); + + PrintWriter w = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out))); + + ClassPrinter p = new ClassPrinter(w); + + ClassInstrumenter ci; + oi.beginTraversal(); + while ((ci = oi.nextClass()) != null) { + try { + p.doClass(ci.getReader()); + } finally { + w.flush(); + } + } + + oi.close(); + } + + private static final char[] hexChars = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; + + private static String makeHex(byte[] bytes, int pos, int len, int padTo) { + StringBuffer b = new StringBuffer(); + for (int i = pos; i < pos + len; i++) { + byte v = bytes[i]; + b.append(hexChars[(v >> 4) & 0xF]); + b.append(hexChars[v & 0xF]); + } + while (b.length() < padTo) { + b.append(' '); + } + return b.toString(); + } + + private static String makeChars(byte[] bytes, int pos, int len) { + StringBuffer b = new StringBuffer(); + for (int i = pos; i < pos + len; i++) { + char ch = (char) bytes[i]; + if (ch < 32 || ch > 127) { + b.append('.'); + } else { + b.append(ch); + } + } + return b.toString(); + } + + private static String getClassName(ClassReader cr, int index) throws InvalidClassFileException { + if (index == 0) { + return "any"; + } else { + return cr.getCP().getCPClass(index); + } + } + + private static String dumpFlags(int flags) { + StringBuffer buf = new StringBuffer(); + Class c = Constants.class; + Field[] fs = c.getDeclaredFields(); + for (int i = 0; i < fs.length; i++) { + String name = fs[i].getName(); + if (name.startsWith("ACC_")) { + int val; + try { + val = fs[i].getInt(null); + } catch (IllegalArgumentException e) { + throw new Error(e.getMessage()); + } catch (IllegalAccessException e) { + throw new Error(e.getMessage()); + } + if ((flags & val) != 0) { + if (buf.length() > 0) { + buf.append(" "); + } + buf.append(name.substring(4).toLowerCase()); + } + } + } + return "0x" + Integer.toString(16, flags) + "(" + buf.toString() + ")"; + } + + private void dumpAttributes(ClassReader cr, int i, ClassReader.AttrIterator attrs) throws InvalidClassFileException, + InvalidBytecodeException, IOException { + for (; attrs.isValid(); attrs.advance()) { + String name = attrs.getName(); + w.write(" " + name + ": @" + Integer.toString(attrs.getRawOffset(), 16) + "\n"); + if (name.equals("Code")) { + CodeReader code = new CodeReader(attrs); + + w.write(" maxstack: " + code.getMaxStack() + "\n"); + w.write(" maxlocals: " + code.getMaxLocals() + "\n"); + + w.write(" bytecode:\n"); + int[] rawHandlers = code.getRawHandlers(); + CTDecoder decoder = new CTDecoder(code); + decoder.decode(); + Disassembler disasm = new Disassembler(decoder.getInstructions(), decoder.getHandlers(), decoder + .getInstructionsToBytecodes()); + disasm.disassembleTo(" ", w); + + w.write(" exception handlers:\n"); + for (int e = 0; e < rawHandlers.length; e += 4) { + w.write(" " + rawHandlers[e] + " to " + rawHandlers[e + 1] + " catch " + getClassName(cr, rawHandlers[e + 3]) + + " at " + rawHandlers[e + 2] + "\n"); + } + + ClassReader.AttrIterator codeAttrs = new ClassReader.AttrIterator(); + code.initAttributeIterator(codeAttrs); + for (; codeAttrs.isValid(); codeAttrs.advance()) { + String cName = codeAttrs.getName(); + w.write(" " + cName + ": " + Integer.toString(codeAttrs.getRawOffset(), 16) + "\n"); + } + + if (printLineNumberInfo) { + int[] map = LineNumberTableReader.makeBytecodeToSourceMap(code); + if (map != null) { + w.write(" line number map:\n"); + String line = null; + int count = 0; + for (int j = 0; j < map.length; j++) { + String line2 = " " + j + ": " + map[j]; + if (line == null || line2 == null || !line2.substring(line2.indexOf(':')).equals(line.substring(line.indexOf(':')))) { + if (count > 1) { + w.write(" (" + count + " times)\n"); + } else if (count > 0) { + w.write("\n"); + } + count = 0; + line = line2; + w.write(line); + } + count++; + } + if (count > 1) { + w.write(" (" + count + " times)\n"); + } else if (count > 0) { + w.write("\n"); + } + } + } + + int[][] locals = LocalVariableTableReader.makeVarMap(code); + if (locals != null) { + w.write(" local variable map:\n"); + String line = null; + int count = 0; + for (int j = 0; j < locals.length; j++) { + int[] vars = locals[j]; + String line2 = null; + if (vars != null) { + StringBuffer buf = new StringBuffer(); + buf.append(" " + j + ":"); + for (int k = 0; k < vars.length; k += 2) { + if (vars[k] != 0) { + String n = cr.getCP().getCPUtf8(vars[k]) + "(" + cr.getCP().getCPUtf8(vars[k + 1]) + ")"; + buf.append(" " + (k / 2) + ":" + n); + } + } + line2 = buf.toString(); + } + if (line == null || line2 == null || !line2.substring(line2.indexOf(':')).equals(line.substring(line.indexOf(':')))) { + if (count > 1) { + w.write(" (" + count + " times)\n"); + } else if (count > 0) { + w.write("\n"); + } + count = 0; + line = line2; + if (line != null) { + w.write(line); + } + } + if (line != null) { + count++; + } + } + if (count > 1) { + w.write(" (" + count + " times)\n"); + } else if (count > 0) { + w.write("\n"); + } + } + } else if (name.equals("ConstantValue")) { + ConstantValueReader cv = new ConstantValueReader(attrs); + w.write(" value: " + getCPItemString(cr.getCP(), cv.getValueCPIndex()) + "\n"); + } else if (name.equals("SourceFile")) { + SourceFileReader sr = new SourceFileReader(attrs); + w.write(" file: " + cr.getCP().getCPUtf8(sr.getSourceFileCPIndex()) + "\n"); + } else { + int len = attrs.getDataSize(); + int pos = attrs.getDataOffset(); + while (len > 0) { + int amount = Math.min(16, len); + w.write(" " + makeHex(cr.getBytes(), pos, amount, 32) + " " + makeChars(cr.getBytes(), pos, amount) + "\n"); + len -= amount; + pos += amount; + } + } + } + } + + private static String getCPItemString(ConstantPoolParser cp, int i) throws InvalidClassFileException { + int t = cp.getItemType(i); + switch (t) { + case ClassConstants.CONSTANT_Utf8: + return "Utf8 " + quoteString(cp.getCPUtf8(i)); + case ClassConstants.CONSTANT_Class: + return "Class " + cp.getCPClass(i); + case ClassConstants.CONSTANT_String: + return "String " + quoteString(cp.getCPString(i)); + case ClassConstants.CONSTANT_Integer: + return "Integer " + cp.getCPInt(i); + case ClassConstants.CONSTANT_Float: + return "Float " + cp.getCPFloat(i); + case ClassConstants.CONSTANT_Double: + return "Double " + cp.getCPDouble(i); + case ClassConstants.CONSTANT_Long: + return "Long " + cp.getCPLong(i); + case ClassConstants.CONSTANT_MethodRef: + return "Method " + cp.getCPRefClass(i) + " " + cp.getCPRefName(i) + " " + cp.getCPRefType(i); + case ClassConstants.CONSTANT_FieldRef: + return "Field " + cp.getCPRefClass(i) + " " + cp.getCPRefName(i) + " " + cp.getCPRefType(i); + case ClassConstants.CONSTANT_InterfaceMethodRef: + return "InterfaceMethod " + cp.getCPRefClass(i) + " " + cp.getCPRefName(i) + " " + cp.getCPRefType(i); + case ClassConstants.CONSTANT_NameAndType: + return "NameAndType " + cp.getCPNATType(i) + " " + cp.getCPNATName(i); + default: + return "Unknown type " + t; + } + } + + private static String quoteString(String string) { + StringBuffer buf = new StringBuffer(); + buf.append('"'); + for (int i = 0; i < string.length(); i++) { + char ch = string.charAt(i); + switch (ch) { + case '\r': + buf.append("\\r"); + break; + case '\n': + buf.append("\\n"); + break; + case '\\': + buf.append("\\\\"); + break; + case '\t': + buf.append("\\t"); + break; + case '\"': + buf.append("\\\""); + break; + default: + if (ch >= 32 && ch <= 127) { + buf.append(ch); + } else { + buf.append("\\u"); + String h = makeHex(new byte[] { (byte) (ch >> 8), (byte) ch }, 0, 2, 0); + for (int j = 4 - h.length(); j > 0; j--) { + buf.append('0'); + } + buf.append(h); + } + } + } + buf.append('"'); + return buf.toString(); + } + + /** + * Print a class. + */ + public void doClass(final ClassReader cr) throws InvalidClassFileException, InvalidBytecodeException, IOException { + w.write("Class: " + cr.getName() + "\n"); + + if (printConstantPool) { + ConstantPoolParser cp = cr.getCP(); + for (int i = 1; i < cp.getItemCount(); i++) { + int t = cp.getItemType(i); + if (t > 0) { + w.write(" Constant pool item " + i + ": "); + w.write(getCPItemString(cp, i)); + w.write("\n"); + } + } + } + + ClassReader.AttrIterator attrs = new ClassReader.AttrIterator(); + cr.initClassAttributeIterator(attrs); + dumpAttributes(cr, 0, attrs); + w.write("\n"); + + int fieldCount = cr.getFieldCount(); + w.write(fieldCount + " fields:\n"); + for (int i = 0; i < fieldCount; i++) { + w.write(cr.getFieldName(i) + " " + cr.getFieldType(i) + " " + dumpFlags(cr.getFieldAccessFlags(i)) + "\n"); + cr.initFieldAttributeIterator(i, attrs); + dumpAttributes(cr, i, attrs); + } + w.write("\n"); + + int methodCount = cr.getMethodCount(); + w.write(methodCount + " methods:\n"); + for (int i = 0; i < methodCount; i++) { + w.write(cr.getMethodName(i) + " " + cr.getMethodType(i) + " " + dumpFlags(cr.getMethodAccessFlags(i)) + "\n"); + cr.initMethodAttributeIterator(i, attrs); + dumpAttributes(cr, i, attrs); + } + w.write("\n"); + } +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/shrikeCT/tools/ClassSearcher.java b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/shrikeCT/tools/ClassSearcher.java new file mode 100644 index 000000000..cef2c9d48 --- /dev/null +++ b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/shrikeCT/tools/ClassSearcher.java @@ -0,0 +1,70 @@ +/******************************************************************************* + * 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.shrikeBT.shrikeCT.tools; + +import java.io.BufferedWriter; +import java.io.FileWriter; +import java.io.Writer; + +import com.ibm.wala.shrikeBT.shrikeCT.ClassInstrumenter; +import com.ibm.wala.shrikeBT.shrikeCT.OfflineInstrumenter; +import com.ibm.wala.shrikeCT.ClassReader; +import com.ibm.wala.shrikeCT.ConstantPoolParser; + +/** + * This is a demo class. + * + * Class files are taken as input arguments (or if there are none, from standard + * input). We search those class files for all references to the Java library + * classes "SoftReference" or "WeakReference". This is just a demo to show how + * to write a simple tool like this. Here we're using the OfflineInstrumenter + * class to manage loading a set of class files and JARs for analysis; we don't + * actually modify any code. + * + * In Unix, I run it like this: java -cp ~/dev/shrike/shrike + * com.ibm.wala.shrikeBT.shrikeCT.tools.ClassSearcher test.jar -o output.jar + */ +public class ClassSearcher { + private static OfflineInstrumenter instrumenter; + + private static int scanned = 0; + + public static void main(String[] args) throws Exception { + instrumenter = new OfflineInstrumenter(); + + Writer w = new BufferedWriter(new FileWriter("report", true)); + + instrumenter.parseStandardArgs(args); + instrumenter.beginTraversal(); + ClassInstrumenter ci; + while ((ci = instrumenter.nextClass()) != null) { + doClass(ci, w, instrumenter.getLastClassResourceName()); + } + instrumenter.close(); + w.close(); + + System.out.println("Classes scanned: " + scanned); + } + + private static void doClass(final ClassInstrumenter ci, Writer w, String resource) throws Exception { + scanned++; + + String cl1 = "java/lang/ref/WeakReference"; + String cl2 = "java/lang/ref/SoftReference"; + ClassReader r = ci.getReader(); + ConstantPoolParser cp = r.getCP(); + for (int i = 1; i < cp.getItemCount(); i++) { + if (cp.getItemType(i) == ConstantPoolParser.CONSTANT_Class && (cp.getCPClass(i).equals(cl1) || cp.getCPClass(i).equals(cl2))) { + w.write(cp.getCPClass(i) + " " + resource + " " + r.getName() + "\n"); + } + } + } +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/shrikeCT/tools/MethodTracer.java b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/shrikeCT/tools/MethodTracer.java new file mode 100644 index 000000000..33e6d5055 --- /dev/null +++ b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/shrikeCT/tools/MethodTracer.java @@ -0,0 +1,150 @@ +/******************************************************************************* + * 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.shrikeBT.shrikeCT.tools; + +import java.io.BufferedWriter; +import java.io.FileWriter; +import java.io.PrintStream; +import java.io.Writer; + +import com.ibm.wala.shrikeBT.ConstantInstruction; +import com.ibm.wala.shrikeBT.Disassembler; +import com.ibm.wala.shrikeBT.Instruction; +import com.ibm.wala.shrikeBT.InvokeInstruction; +import com.ibm.wala.shrikeBT.MethodData; +import com.ibm.wala.shrikeBT.MethodEditor; +import com.ibm.wala.shrikeBT.Util; +import com.ibm.wala.shrikeBT.analysis.Verifier; +import com.ibm.wala.shrikeBT.shrikeCT.ClassInstrumenter; +import com.ibm.wala.shrikeBT.shrikeCT.OfflineInstrumenter; + +/** + * This is a demo class. + * + * Class files are taken as input arguments (or if there are none, from standard + * input). The methods in those files are instrumented: we insert a + * System.err.println() at ever method call, and a System.err.println() at every + * method entry. + * + * In Unix, I run it like this: java -cp ~/dev/shrike/shrike + * com.ibm.wala.shrikeBT.shrikeCT.tools.MethodTracer test.jar -o output.jar + * + * All modified classes are copied into "output.jar". Some classes may not be + * modified. To run the resulting code, you should put output.jar and test.jar + * on the classpath, and put output.jar before test.jar. Disassembled code is + * written to the file "report" under the current directory. + */ +public class MethodTracer { + private final static boolean disasm = true; + private final static boolean verify = true; + private final static boolean INSTRUMENT_CALLERS = false; + + private static OfflineInstrumenter instrumenter; + + public static void main(String[] args) throws Exception { + for (int i = 0; i < 1; i++) { + instrumenter = new OfflineInstrumenter(); + + Writer w = new BufferedWriter(new FileWriter("report", false)); + + instrumenter.parseStandardArgs(args); + instrumenter.setPassUnmodifiedClasses(false); + instrumenter.beginTraversal(); + ClassInstrumenter ci; + while ((ci = instrumenter.nextClass()) != null) { + doClass(ci, w); + } + instrumenter.close(); + } + } + + // Keep these commonly used instructions around. This trick can speed up + // instrumentation tools a bit. It's always safe because Instruction objects + // are always immutable and shareable. + static final Instruction getSysErr = Util.makeGet(System.class, "err"); + static final Instruction callPrintln = Util.makeInvoke(PrintStream.class, "println", new Class[] { String.class }); + + private static void doClass(final ClassInstrumenter ci, Writer w) throws Exception { + w.write("Class: " + ci.getReader().getName() + "\n"); + w.flush(); + + for (int i = 0; i < ci.getReader().getMethodCount(); i++) { + MethodData d = ci.visitMethod(i); + + // d could be null, e.g., if the method is abstract or native + if (d != null) { + w.write("Instrumenting " + ci.getReader().getMethodName(i) + " " + ci.getReader().getMethodType(i) + ":\n"); + w.flush(); + + if (disasm) { + w.write("Initial ShrikeBT code:\n"); + (new Disassembler(d)).disassembleTo(w); + w.flush(); + } + + if (verify) { + // verify the incoming code + Verifier v = new Verifier(d); + v.verify(); + } + + MethodEditor me = new MethodEditor(d); + me.beginPass(); + final String msg0 = "Call to " + Util.makeClass("L" + ci.getReader().getName() + ";") + "." + + ci.getReader().getMethodName(i); + + me.insertAtStart(new MethodEditor.Patch() { + public void emitTo(MethodEditor.Output w) { + w.emit(getSysErr); + w.emit(ConstantInstruction.makeString(msg0)); + w.emit(callPrintln); + } + }); + if (INSTRUMENT_CALLERS) { + Instruction[] ins = d.getInstructions(); + for (int k = 0; k < ins.length; k++) { + if (ins[k] instanceof InvokeInstruction) { + InvokeInstruction instr = (InvokeInstruction) ins[k]; + final String msg = "Call from " + Util.makeClass("L" + ci.getReader().getName() + ";") + "." + + ci.getReader().getMethodName(i) + ":" + k + " to target " + Util.makeClass(instr.getClassType()) + "." + + instr.getMethodName(); + me.insertBefore(k, new MethodEditor.Patch() { + public void emitTo(MethodEditor.Output w) { + w.emit(getSysErr); + w.emit(ConstantInstruction.makeString(msg)); + w.emit(callPrintln); + } + }); + } + } + } + // this updates the data d + me.applyPatches(); + + if (disasm) { + w.write("Final ShrikeBT code:\n"); + (new Disassembler(d)).disassembleTo(w); + w.flush(); + } + + if (verify) { + // verify outgoing code + Verifier v = new Verifier(d); + v.verify(); + } + } + } + + if (ci.isChanged()) { + instrumenter.outputModifiedClass(ci); + } + } +} diff --git a/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/tools/MethodOptimizer.java b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/tools/MethodOptimizer.java new file mode 100644 index 000000000..3c47bcd56 --- /dev/null +++ b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/tools/MethodOptimizer.java @@ -0,0 +1,463 @@ +/******************************************************************************* + * 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.shrikeBT.tools; + +import java.util.Arrays; +import java.util.BitSet; + +import com.ibm.wala.shrikeBT.DupInstruction; +import com.ibm.wala.shrikeBT.ExceptionHandler; +import com.ibm.wala.shrikeBT.Instruction; +import com.ibm.wala.shrikeBT.LoadInstruction; +import com.ibm.wala.shrikeBT.MethodData; +import com.ibm.wala.shrikeBT.MethodEditor; +import com.ibm.wala.shrikeBT.PopInstruction; +import com.ibm.wala.shrikeBT.StoreInstruction; +import com.ibm.wala.shrikeBT.Util; +import com.ibm.wala.shrikeBT.MethodEditor.Output; +import com.ibm.wala.shrikeBT.info.LocalAllocator; + +public final class MethodOptimizer { + private MethodData data; + private Instruction[] instructions; + private ExceptionHandler[][] handlers; + private MethodEditor editor; + // The value at index [i][N] is the index of the only instruction which pushes + // a value onto + // the stack which is #N popped by instruction i, or -2 if there is no such + // instruction + // or -1 if there is more than one such instruction. + private int[][] uniqueStackDefLocations; + // The value at index i[N] is the index of the only instruction which pops a + // value off + // the stack which is pushed by instruction i, or -2 if there is no such + // instruction + // or -1 if there is more than one such instruction. + private int[] uniqueStackUseLocations; + private int[] stackSizes; + private int[][] backEdges; + // The value at index i is the index of the only instruction which stores a + // value onto + // the stack which is popped by instruction i, or -2 if there is no such + // instruction + // or -1 if there is more than one such instruction. + + final static int[] noEdges = new int[0]; + + public MethodOptimizer(MethodData d, MethodEditor e) { + this.data = d; + this.editor = e; + } + + public MethodOptimizer(MethodData d) { + this(d, new MethodEditor(d)); + } + + public class UnoptimizableCodeException extends Exception { + private static final long serialVersionUID = 2543170335674010642L; + + public UnoptimizableCodeException(String s) { + super(s); + } + } + + public int findUniqueStackDef(int instr, int stack) throws UnoptimizableCodeException { + instructions = editor.getInstructions(); + handlers = editor.getHandlers(); + checkConsistentStackSizes(); + buildBackEdges(); + buildStackDefMap(); + + return uniqueStackDefLocations[instr][stack]; + } + + public void optimize() throws UnoptimizableCodeException { + boolean changed; + do { + instructions = editor.getInstructions(); + handlers = editor.getHandlers(); + checkConsistentStackSizes(); + buildBackEdges(); + + editor.beginPass(); + buildStackDefMap(); + pushBackLocalStores(); + forwardDups(); + changed = editor.applyPatches(); + editor.endPass(); + } while (changed); + } + + private void buildBackEdges() { + int[] backEdgeCount = new int[instructions.length]; + + for (int i = 0; i < instructions.length; i++) { + int[] targets = instructions[i].getBranchTargets(); + for (int j = 0; j < targets.length; j++) { + backEdgeCount[targets[j]]++; + } + ExceptionHandler[] hs = handlers[i]; + for (int j = 0; j < hs.length; j++) { + backEdgeCount[hs[j].getHandler()]++; + } + } + + backEdges = new int[instructions.length][]; + for (int i = 0; i < backEdges.length; i++) { + if (backEdgeCount[i] > 0) { + backEdges[i] = new int[backEdgeCount[i]]; + } else { + backEdges[i] = noEdges; + } + } + Arrays.fill(backEdgeCount, 0); + + for (int i = 0; i < instructions.length; i++) { + int[] targets = instructions[i].getBranchTargets(); + for (int j = 0; j < targets.length; j++) { + int target = targets[j]; + backEdges[target][backEdgeCount[target]] = i; + backEdgeCount[target]++; + } + ExceptionHandler[] hs = handlers[i]; + for (int j = 0; j < hs.length; j++) { + int target = hs[j].getHandler(); + backEdges[target][backEdgeCount[target]] = i; + backEdgeCount[target]++; + } + } + } + + private int checkConsistentStackSizes() throws UnoptimizableCodeException { + stackSizes = new int[instructions.length]; + Arrays.fill(stackSizes, -1); + + checkStackSizesAt(0, 0); + + int result = 0; + for (int i = 0; i < stackSizes.length; i++) { + result = Math.max(result, stackSizes[i]); + } + return result; + } + + private void checkStackSizesAt(int instruction, int stackSize) throws UnoptimizableCodeException { + while (true) { + if (instruction < 0 || instruction >= instructions.length) { + throw new UnoptimizableCodeException("Code exits in an illegal way"); + } + if (stackSizes[instruction] != -1) { + if (stackSizes[instruction] != stackSize) { + throw new UnoptimizableCodeException("Mismatched stack sizes at " + instruction + ": " + stackSize + " and " + + stackSizes[instruction]); + } else { + return; + } + } + stackSizes[instruction] = stackSize; + + Instruction instr = instructions[instruction]; + stackSize -= instr.getPoppedCount(); + if (stackSize < 0) { + throw new UnoptimizableCodeException("Stack underflow at " + instruction); + } + if (instr instanceof DupInstruction) { + DupInstruction d = (DupInstruction) instr; + stackSize += d.getSize() + d.getPoppedCount(); + } else if (instr.getPushedType(null) != null) { + stackSize++; + } + + int[] targets = instr.getBranchTargets(); + for (int i = 0; i < targets.length; i++) { + checkStackSizesAt(targets[i], stackSize); + } + + ExceptionHandler[] hs = handlers[instruction]; + for (int i = 0; i < hs.length; i++) { + checkStackSizesAt(hs[i].getHandler(), 1); + } + + if (!instr.isFallThrough()) { + return; + } + + instruction++; + } + } + + private static boolean instructionKillsVar(Instruction instr, int v) { + if (instr instanceof StoreInstruction) { + StoreInstruction st = (StoreInstruction) instr; + return st.getVarIndex() == v || (Util.getWordSize(st.getType()) == 2 && st.getVarIndex() + 1 == v); + } else { + return false; + } + } + + private void forwardDups() { + for (int i = 0; i < instructions.length; i++) { + Instruction instr = instructions[i]; + if (instr instanceof DupInstruction && ((DupInstruction) instr).getDelta() == 0 && uniqueStackDefLocations[i][0] >= 0 + && instructions[uniqueStackDefLocations[i][0]] instanceof LoadInstruction) { + int source = uniqueStackDefLocations[i][0]; + final LoadInstruction li = (LoadInstruction) instructions[source]; + + for (int j = 0; j < instructions.length; j++) { + int[] locs = uniqueStackDefLocations[j]; + if (locs[0] == i) { + // check to see if the variable is killed along any path from the + // dup + // to its use + BitSet path = getInstructionsOnPath(source, j); + boolean killed = false; + int v = li.getVarIndex(); + for (int k = 0; j < instructions.length && !killed; k++) { + if (path.get(k)) { + if (instructionKillsVar(instructions[k], v)) { + killed = true; + } + } + } + + if (!killed) { + editor.insertBefore(j, new MethodEditor.Patch() { + public void emitTo(Output w) { + w.emit(PopInstruction.make(1)); + w.emit(li); + } + }); + } + } + } + } + } + } + + private void pushBackLocalStores() { + for (int i = 0; i < instructions.length; i++) { + Instruction instr = instructions[i]; + if (instr instanceof StoreInstruction && uniqueStackDefLocations[i][0] >= 0 && uniqueStackDefLocations[i][0] != i - 1 + && uniqueStackUseLocations[uniqueStackDefLocations[i][0]] == i) { + final StoreInstruction s = (StoreInstruction) instr; + int source = uniqueStackDefLocations[i][0]; + + // Check if the path from source to i contains anything killing the + // variable + BitSet path = getInstructionsOnPath(source, i); + boolean killed = false; + int v = s.getVarIndex(); + for (int j = 0; j < instructions.length && !killed; j++) { + if (path.get(j)) { + if (instructionKillsVar(instructions[j], v)) { + killed = true; + } + } + } + + if (killed) { + final String type = s.getType(); + final int newVar = LocalAllocator.allocate(data, type); + // put a store to the newVar right after the source + editor.insertAfter(source, new MethodEditor.Patch() { + public void emitTo(Output w) { + w.emit(StoreInstruction.make(type, newVar)); + } + }); + // load newVar before storing to correct variable + editor.insertBefore(i, new MethodEditor.Patch() { + public void emitTo(Output w) { + w.emit(LoadInstruction.make(type, newVar)); + } + }); + } else { + // remove store instruction + editor.replaceWith(i, new MethodEditor.Patch() { + public void emitTo(Output w) { + } + }); + // replace it right after the source + editor.insertAfter(source, new MethodEditor.Patch() { + public void emitTo(Output w) { + w.emit(s); + } + }); + } + } + } + } + + private void buildStackDefMap() { + int[][] abstractStacks = new int[instructions.length][]; + + for (int i = 0; i < instructions.length; i++) { + abstractStacks[i] = new int[stackSizes[i]]; + Arrays.fill(abstractStacks[i], -2); + } + + for (int i = 0; i < instructions.length; i++) { + if (instructions[i] instanceof DupInstruction) { + DupInstruction d = (DupInstruction) instructions[i]; + for (int j = 0; j < 2 * d.getSize() + d.getDelta(); j++) { + followStackDef(abstractStacks, i, i + 1, stackSizes[i + 1] - 1 - j); + } + } else if (instructions[i].getPushedType(null) != null) { + followStackDef(abstractStacks, i, i + 1, stackSizes[i + 1] - 1); + } + } + + uniqueStackDefLocations = new int[instructions.length][]; + for (int i = 0; i < instructions.length; i++) { + uniqueStackDefLocations[i] = new int[instructions[i].getPoppedCount()]; + int popped = instructions[i].getPoppedCount(); + System.arraycopy(abstractStacks[i], stackSizes[i] - popped, uniqueStackDefLocations[i], 0, popped); + } + + uniqueStackUseLocations = new int[instructions.length]; + Arrays.fill(uniqueStackUseLocations, -2); + + for (int i = 0; i < instructions.length; i++) { + abstractStacks[i] = new int[stackSizes[i]]; + Arrays.fill(abstractStacks[i], -2); + } + + for (int i = 0; i < instructions.length; i++) { + int count = instructions[i].getPoppedCount(); + if (count == 1) { + followStackUse(abstractStacks, i, i, stackSizes[i] - 1); + } else if (count > 1) { + for (int j = 0; j < count; j++) { + followStackUse(abstractStacks, -1, i, stackSizes[i] - 1 - j); + } + } + } + + for (int i = 0; i < instructions.length; i++) { + if (instructions[i].getPushedType(null) != null) { + uniqueStackUseLocations[i] = abstractStacks[i + 1][stackSizes[i + 1] - 1]; + } + } + } + + private void followStackDef(int[][] abstractDefStacks, int def, int instruction, int stackPointer) { + while (true) { + int[] stack = abstractDefStacks[instruction]; + if (stackPointer >= stack.length) { + // the value must have been popped off by the last instruction + return; + } + + if (stack[stackPointer] == -2) { + stack[stackPointer] = def; + } else if (stack[stackPointer] == def) { + return; + } else if (stack[stackPointer] == -1) { + return; + } else { + stack[stackPointer] = -1; + def = -1; + } + + int[] targets = instructions[instruction].getBranchTargets(); + for (int i = 0; i < targets.length; i++) { + followStackDef(abstractDefStacks, def, targets[i], stackPointer); + } + + ExceptionHandler[] hs = handlers[instruction]; + for (int i = 0; i < hs.length; i++) { + followStackDef(abstractDefStacks, -1, hs[i].getHandler(), 0); + } + + if (!instructions[instruction].isFallThrough()) { + return; + } + instruction++; + } + } + + private void followStackUse(int[][] abstractUseStacks, int use, int instruction, int stackPointer) { + while (true) { + int[] stack = abstractUseStacks[instruction]; + if (stackPointer >= stack.length) { + // the value must have been pushed by this instruction + return; + } + + if (stack[stackPointer] == -2) { + stack[stackPointer] = use; + } else if (stack[stackPointer] == use || stack[stackPointer] == -1) { + return; + } else { + stack[stackPointer] = -1; + use = -1; + } + + int[] back = backEdges[instruction]; + for (int i = 0; i < back.length; i++) { + followStackUse(abstractUseStacks, use, back[i], stackPointer); + } + + if (instruction == 0 || !instructions[instruction - 1].isFallThrough()) { + return; + } + instruction--; + } + } + + private BitSet getInstructionsOnPath(int from, int to) { + BitSet reachable = new BitSet(); + getReachableInstructions(reachable, from, to); + BitSet reaching = new BitSet(); + getReachingInstructions(reaching, from, to); + reachable.and(reaching); + return reachable; + } + + private void getReachableInstructions(BitSet bits, int from, int to) { + while (true) { + if (from == to) { + return; + } + + bits.set(from); + + int[] targets = instructions[from].getBranchTargets(); + for (int i = 0; i < targets.length; i++) { + getReachableInstructions(bits, targets[i], to); + } + + if (!instructions[from].isFallThrough()) { + return; + } + from++; + } + } + + private void getReachingInstructions(BitSet bits, int from, int to) { + while (true) { + if (to == from) { + return; + } + + bits.set(to); + + int[] targets = backEdges[to]; + for (int i = 0; i < targets.length; i++) { + getReachingInstructions(bits, from, targets[i]); + } + + if (to == 0 || !instructions[to - 1].isFallThrough()) { + return; + } + to--; + } + } +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/tools/OfflineInstrumenterBase.java b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/tools/OfflineInstrumenterBase.java new file mode 100644 index 000000000..cd9dbbea6 --- /dev/null +++ b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/tools/OfflineInstrumenterBase.java @@ -0,0 +1,581 @@ +/******************************************************************************* + * 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.shrikeBT.tools; + +import java.io.BufferedInputStream; +import java.io.BufferedOutputStream; +import java.io.BufferedReader; +import java.io.File; +import java.io.FileFilter; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.BitSet; +import java.util.Enumeration; +import java.util.HashSet; +import java.util.jar.JarEntry; +import java.util.jar.JarFile; +import java.util.jar.JarOutputStream; +import java.util.zip.ZipEntry; + +/** + * This class provides functionality for performing offline instrumentation. It + * is subclassed with class-toolkit-specific functionality. + */ +public abstract class OfflineInstrumenterBase { + private int inputIndex; + private HashSet entryNames = new HashSet(); + private ArrayList inputs = new ArrayList(); + private BitSet ignoringInputs = new BitSet(); + private File outputFile; + private boolean passUnmodifiedClasses = false; + + private JarOutputStream outputJar; + + private JarFile cachedJar; + private File cachedJarFile; + + private ManifestBuilder manifestBuilder; + + /** + * This installs a ManifestBuilder callback that this class will notify + * whenever an entry has been added to the output zip file. + */ + public void setManifestBuilder(ManifestBuilder mb) { + manifestBuilder = mb; + } + + /** + * Thiscallback is notified whenever an entry has been added to the output zip + * file. + */ + public static interface ManifestBuilder { + public void addEntry(ZipEntry ze); + } + + /** + * This class represents a resource which can be opened and read; either a + * file or a JAR entry. + */ + abstract class Input { + private String className; + + /** + * Tell us what the classname is supposed to be, if it's a class file. + */ + public final void setClassName(String c) { + className = c.intern(); + } + + /** + * Returns the classname if it has been set. + */ + public final String getClassName() { + return className; + } + + /** + * Open the resource for reading as a stream. + */ + public abstract InputStream open() throws IOException; + + /** + * @return true if this resource represents a class, false otherwise + */ + public boolean isClass() { + return true; + } + } + + /** + * This class represents a JAR file entry. It might or might not be a class; + * we support non-class JAR resources so that we can copy them to the output + * JAR if the client requests that. + */ + final class JarInput extends Input { + private File file; + private String name; + + /** + * Select a particular entry from a JAR file on disk. + */ + public JarInput(File f, String je) { + file = f; + name = je; + } + + public InputStream open() throws IOException { + JarFile cachedJar = openCachedJar(file); + return cachedJar.getInputStream(cachedJar.getEntry(name)); + } + + public String toString() { + return file.getPath() + "#" + name; + } + + public boolean isClass() { + return name.endsWith(".class"); + } + + /** + * Get the underlying ZipEntry corresponding to this resource. + */ + public ZipEntry getEntry() throws IOException { + JarFile cachedJar = openCachedJar(file); + return cachedJar.getEntry(name); + } + } + + /** + * Open a JAR/ZIP file. This routine caches the last JAR file opened to save + * effort when the same file is accessed again and again. DO NOT close the + * file returned by this routine until you've finished with this + * OfflineInstrumente completely. Also, this JarFile will be closed the next + * time someone calls openCachedJar. + */ + private JarFile openCachedJar(File file) throws IOException { + if (cachedJarFile != null && cachedJarFile.equals(file)) { + return cachedJar; + } else { + if (cachedJar != null) { + cachedJar.close(); + } + cachedJarFile = file; + cachedJar = new JarFile(file); + return cachedJar; + } + } + + /** + * This class represents a plain old class file in the filesystem. Non-class + * file resources are not supported. + */ + final class ClassInput extends Input { + private File file; + + public ClassInput(File f) { + file = f; + } + + public InputStream open() throws IOException { + return new FileInputStream(file); + } + + public String toString() { + return file.getPath(); + } + } + + protected OfflineInstrumenterBase() { + } + + /** + * Set the file in which instrumented classes will be deposited. + */ + final public void setOutputJar(File f) { + outputFile = f; + } + + /** + * Indicate whether classes which are not modified will be put into the output + * jar anyway. + */ + final public void setPassUnmodifiedClasses(boolean pass) { + passUnmodifiedClasses = pass; + } + + /** + * Add a JAR file containing source classes to instrument. + */ + final public void addInputJar(File f) throws IOException { + JarFile jf = new JarFile(f); + for (Enumeration e = jf.entries(); e.hasMoreElements();) { + JarEntry entry = (JarEntry) e.nextElement(); + if (!entry.isDirectory()) { + String name = entry.getName(); + inputs.add(new JarInput(f, name)); + } + } + jf.close(); + } + + /** + * Add a JAR entry containing a source class to instrument. + */ + final public void addInputJarEntry(File f, String name) throws IOException { + inputs.add(new JarInput(f, name)); + } + + /** + * Add a class file containing a source class to instrument. + */ + final public void addInputClass(File f) { + inputs.add(new ClassInput(f)); + } + + /** + * Add a directory containing class files to instrument. All subdirectories + * are also scanned. + */ + final public void addInputDirectory(File d) throws IOException { + File[] fs = d.listFiles(new FileFilter() { + public boolean accept(File f) { + return f.isDirectory() || f.getName().endsWith(".class"); + } + }); + for (int i = 0; i < fs.length; i++) { + File f = fs[i]; + if (f.isDirectory()) { + addInputDirectory(f); + } else { + addInputClass(f); + } + } + } + + /** + * Add something to instrument --- the name of a JAR file, a class file, a + * directory or an entry within a jar file (as filename#entryname). If we + * can't identify it, nothing is added and we return false. + */ + final public boolean addInputElement(String a) throws IOException { + try { + int poundIndex = a.indexOf('#'); + if (poundIndex > 0) { + addInputJarEntry(new File(a.substring(0, poundIndex)), a.substring(poundIndex + 1)); + return true; + } + File f = new File(a); + if (f.isDirectory()) { + addInputDirectory(f); + return true; + } else if (f.exists()) { + if (a.endsWith(".class")) { + addInputClass(f); + return true; + } else if (a.endsWith(".jar") || a.endsWith(".zip")) { + addInputJar(new File(a)); + return true; + } + } + } catch (IOException ex) { + throw new IOException("Error reading input element '" + a + "': " + ex.getMessage()); + } + return false; + } + + /** + * Parse an argument list to find elements to instrument and the name of the + * output file. The "-o filename" option selects the output JAR file name. Any + * other argument not starting with "-" is added to the list of elements to + * instrument, if it appears to be the name of a class file, JAR file, or + * directory. If any argument starting with "--" is encountered, the rest of + * the command-line is considered leftover + * + * @return the arguments that were not understood + */ + final public String[] parseStandardArgs(String[] args) throws IOException { + ArrayList leftover = new ArrayList(); + + for (int i = 0; i < args.length; i++) { + String a = args[i]; + if (a.equals("-o") && i + 1 < args.length) { + setOutputJar(new File(args[i + 1])); + i++; + continue; + } else if (!a.startsWith("-")) { + if (addInputElement(a)) { + continue; + } + } else if (a.startsWith("--")) { + for (int j = i; j < args.length; j++) { + leftover.add(args[j]); + } + break; + } + leftover.add(a); + } + + String[] r = new String[leftover.size()]; + leftover.toArray(r); + return r; + } + + /** + * @return the number of source classes to be instrumented + */ + final public int getNumInputClasses() { + return inputs.size(); + } + + /** + * Read a list of class file names from a stream and add them to the list of + * things to instrument. + */ + final public void readInputClasses(InputStream s) throws IOException { + String str; + BufferedReader r = new BufferedReader(new InputStreamReader(s)); + while ((str = r.readLine()) != null) { + addInputElement(str); + } + } + + /** + * Start traversing the source class list from the beginning. + */ + final public void beginTraversal() { + inputIndex = 0; + } + + protected abstract Object makeClassFromStream(BufferedInputStream s) throws IOException; + + protected abstract String getClassName(Object cl); + + protected abstract void writeClassTo(Object cl, Object mods, OutputStream s) throws IOException; + + final protected Object internalNextClass() throws IOException { + while (true) { + if (inputIndex >= inputs.size()) { + return null; + } else { + Input in = inputs.get(inputIndex); + inputIndex++; + if (ignoringInputs.get(inputIndex - 1) || !in.isClass()) { + continue; + } + BufferedInputStream s = new BufferedInputStream(in.open()); + try { + Object r = makeClassFromStream(s); + String name = getClassName(r); + in.setClassName(name); + return r; + } finally { + s.close(); + } + } + } + } + + private static String toEntryName(String className) { + return className.replace('.', '/') + ".class"; + } + + /** + * Get the name of the resource containing the last class returned. This is + * either a file name (e.g., "com/ibm/Main.class"), or a JAR entry name (e.g., + * "apps/app.jar#com/ibm/Main.class"). + * + * @return the resource name, or null if no class has been returned yet + */ + final public String getLastClassResourceName() { + if (inputIndex < 1) { + return null; + } else { + Input in = inputs.get(inputIndex - 1); + return in.toString(); + } + } + + /** + * Returns the File we are storing classes into. + */ + final public File getOutputFile() { + return outputFile; + } + + final protected boolean internalOutputModifiedClass(Object cf, Object mods) throws IOException { + makeOutputJar(); + String name = toEntryName(getClassName(cf)); + if (entryNames.contains(name)) { + return false; + } else { + putNextEntry(new ZipEntry(name)); + BufferedOutputStream s = new BufferedOutputStream(outputJar); + writeClassTo(cf, mods, s); + s.flush(); + outputJar.closeEntry(); + return true; + } + } + + /** + * Set the JAR Comment for the output JAR. + */ + final public void setJARComment(String comment) throws IOException { + makeOutputJar(); + outputJar.setComment(comment); + } + + final void makeOutputJar() throws IOException { + if (outputJar == null) { + if (outputFile == null) { + throw new IllegalArgumentException("Output file was not set"); + } + + outputJar = new JarOutputStream(new FileOutputStream(outputFile)); + } + } + + /** + * Skip the last class returned in every future traversal of the class list. + */ + final public void setIgnore(boolean ignore) { + if (inputIndex == 0) { + throw new IllegalArgumentException("Must get a class before ignoring it"); + } + + ignoringInputs.set(inputIndex - 1); + } + + private static byte[] cachedBuf; + + private static synchronized byte[] makeBuf() { + if (cachedBuf != null) { + byte[] r = cachedBuf; + cachedBuf = null; + return r; + } else { + return new byte[60000]; + } + } + + private static synchronized void releaseBuf(byte[] buf) { + cachedBuf = buf; + } + + public static void copyStream(InputStream in, OutputStream out) throws IOException { + byte[] buf = makeBuf(); + try { + while (true) { + int read = in.read(buf); + if (read < 0) { + return; + } + out.write(buf, 0, read); + } + } finally { + releaseBuf(buf); + } + } + + /** + * Add a raw ZipEntry to the output JAR. Call endOutputJarEntry() when you're + * done. + * + * @return the OutputStream to be used to write the entry contents + */ + final public OutputStream addOutputJarEntry(ZipEntry ze) throws IOException { + putNextEntry(ze); + return outputJar; + } + + /** + * Complete and flush the entry initiated by addOutputJarEntry. + */ + final public void endOutputJarEntry() throws IOException { + outputJar.closeEntry(); + } + + /** + * Call this to copy any unmodified classes to the output. This is called + * automatically by close(); you should only call this if you want to write an + * entry to the JAR file *after* the unmodified classes. This will only ever + * be called once per output JAR. + */ + final public void writeUnmodifiedClasses() throws IOException { + passUnmodifiedClasses = false; + makeOutputJar(); + for (int i = 0; i < inputs.size(); i++) { + Input in = inputs.get(i); + if (!in.isClass()) { + if (in instanceof JarInput) { + JarInput jin = (JarInput) in; + ZipEntry entry = jin.getEntry(); + InputStream s = jin.open(); + try { + ZipEntry newEntry = new ZipEntry(entry.getName()); + newEntry.setComment(entry.getComment()); + newEntry.setExtra(entry.getExtra()); + newEntry.setTime(entry.getTime()); + putNextEntry(newEntry); + copyStream(s, outputJar); + outputJar.closeEntry(); + } finally { + s.close(); + } + } else { + throw new Error("Unknown non-class input: " + in); + } + } else { + String name = in.getClassName(); + if (name == null) { + BufferedInputStream s = new BufferedInputStream(in.open(), 65536); + try { + Object cl = makeClassFromStream(s); + String entryName = toEntryName(getClassName(cl)); + if (!entryNames.contains(entryName)) { + putNextEntry(new ZipEntry(entryName)); + BufferedOutputStream clOut = new BufferedOutputStream(outputJar); + writeClassTo(cl, null, clOut); + clOut.flush(); + outputJar.closeEntry(); + } + } finally { + s.close(); + } + } else { + String entryName = toEntryName(name); + if (!entryNames.contains(entryName)) { + BufferedInputStream s = new BufferedInputStream(in.open()); + try { + putNextEntry(new ZipEntry(entryName)); + BufferedOutputStream clOut = new BufferedOutputStream(outputJar); + copyStream(s, clOut); + clOut.flush(); + outputJar.closeEntry(); + } finally { + s.close(); + } + } + } + } + } + } + + /** + * Call this when you're done modifying classes. + */ + final public void close() throws IOException { + if (passUnmodifiedClasses) { + writeUnmodifiedClasses(); + } + + if (outputJar != null) { + outputJar.close(); + } + + if (cachedJar != null) { + cachedJar.close(); + } + } + + private void putNextEntry(ZipEntry newEntry) throws IOException { + outputJar.putNextEntry(newEntry); + entryNames.add(newEntry.getName()); + if (manifestBuilder != null) { + manifestBuilder.addEntry(newEntry); + } + } +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeCT/ClassConstants.java b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeCT/ClassConstants.java new file mode 100644 index 000000000..e6f41e1d9 --- /dev/null +++ b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeCT/ClassConstants.java @@ -0,0 +1,45 @@ +/******************************************************************************* + * 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.shrikeCT; + +/** + * This interface defines class file constants used by ShrikeCT. The names and + * values are taken directly from the JVM spec. + */ +public interface ClassConstants { + public static final int MAGIC = 0xCAFEBABE; + + public static final byte CONSTANT_Utf8 = 1; + public static final byte CONSTANT_Integer = 3; + public static final byte CONSTANT_Float = 4; + public static final byte CONSTANT_Long = 5; + public static final byte CONSTANT_Double = 6; + public static final byte CONSTANT_Class = 7; + public static final byte CONSTANT_String = 8; + public static final byte CONSTANT_FieldRef = 9; + public static final byte CONSTANT_MethodRef = 10; + public static final byte CONSTANT_InterfaceMethodRef = 11; + public static final byte CONSTANT_NameAndType = 12; + + public static final short ACC_PUBLIC = 0x1; + public static final short ACC_PRIVATE = 0x2; + public static final short ACC_PROTECTED = 0x4; + public static final short ACC_STATIC = 0x8; + public static final short ACC_FINAL = 0x10; + public static final short ACC_SYNCHRONIZED = 0x20; + public static final short ACC_SUPER = 0x20; + public static final short ACC_VOLATILE = 0x40; + public static final short ACC_TRANSIENT = 0x80; + public static final short ACC_NATIVE = 0x100; + public static final short ACC_INTERFACE = 0x200; + public static final short ACC_ABSTRACT = 0x400; + public static final short ACC_STRICT = 0x800; +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeCT/ClassReader.java b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeCT/ClassReader.java new file mode 100644 index 000000000..3b36c84a1 --- /dev/null +++ b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeCT/ClassReader.java @@ -0,0 +1,664 @@ +/******************************************************************************* + * 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.shrikeCT; + +/** + * This is the core class for reading class file data. + * + * ClassReader performs lazy parsing, and thus most of the methods can throw an + * InvalidClassFileException. + */ +public final class ClassReader implements ClassConstants { + private byte[] bytes; + private int[] methodOffsets; + private int[] fieldOffsets; + private ConstantPoolParser cpParser; + private int classInfoOffset; + private int attrInfoOffset; + private int interfaceCount; + + /** + * Build a reader. + * + * If the class file data is corrupt an exception might not be thrown + * immediately. Instead an exception might be thrown later, during the + * execution of some access method. This is a consequence of the 'lazy + * parsing' performed by ClassReader. + * + * @param bytes + * the class file data + * @throws InvalidClassFileException + * the class file data is corrupt + */ + public ClassReader(byte[] bytes) throws InvalidClassFileException { + this.bytes = bytes; + parse(); + } + + private void checkLength(int offset, int required) throws InvalidClassFileException { + if (bytes.length < offset + required) { + throw new InvalidClassFileException(offset, "file truncated, expected " + required + " bytes, saw only " + + (bytes.length - offset)); + } + } + + private void parse() throws InvalidClassFileException { + int offset = 0; + + checkLength(offset, 10); + int magic = getInt(offset); + int minorVersion = getUShort(offset + 4); + int majorVersion = getUShort(offset + 6); + int constantPoolCount = getUShort(offset + 8); + offset += 10; + + if (magic != MAGIC) { + throw new InvalidClassFileException(offset, "bad magic number: " + magic); + } + if (majorVersion < 45 || majorVersion > 49) { + throw new InvalidClassFileException(offset, "unknown class file version: " + majorVersion + "." + minorVersion); + } + + cpParser = new ConstantPoolParser(bytes, offset, constantPoolCount); + offset += cpParser.getRawSize(); + + classInfoOffset = offset; + checkLength(offset, 8); + // int accessFlags = getUShort(offset); + // int thisClass = getUShort(offset + 2); + // int superClass = getUShort(offset + 4); + interfaceCount = getUShort(offset + 6); + if (interfaceCount < 0) { + throw new InvalidClassFileException(offset, "negative interface count: " + interfaceCount); + } + offset += 8; + checkLength(offset, interfaceCount * 2); + offset += interfaceCount * 2; + + checkLength(offset, 2); + int fieldCount = getUShort(offset); + if (fieldCount < 0) { + throw new InvalidClassFileException(offset, "negative field count: " + interfaceCount); + } + offset = parseFields(offset + 2, fieldCount); + + checkLength(offset, 2); + int methodCount = getUShort(offset); + if (methodCount < 0) { + throw new InvalidClassFileException(offset, "negative method count: " + interfaceCount); + } + offset = parseMethods(offset + 2, methodCount); + + attrInfoOffset = offset; + checkLength(offset, 2); + int attrCount = getUShort(offset); + offset = skipAttributes(offset + 2, attrCount); + + if (offset != bytes.length) { + throw new InvalidClassFileException(offset, "extra data in class file"); + } + } + + private int skipAttributes(int offset, int count) throws InvalidClassFileException { + if (count < 0) { + throw new InvalidClassFileException(offset, "negative attribute count: " + interfaceCount); + } + + for (int i = 0; i < count; i++) { + checkLength(offset, 6); + int size = getInt(offset + 2); + if (size < 0) { + throw new InvalidClassFileException(offset, "negative attribute size: " + size); + } + offset += 6; + checkLength(offset, size); + offset += size; + } + return offset; + } + + private int parseFields(int offset, int count) throws InvalidClassFileException { + fieldOffsets = new int[count + 1]; + for (int i = 0; i < count; i++) { + fieldOffsets[i] = offset; + checkLength(offset, 8); + offset = skipAttributes(offset + 8, getUShort(offset + 6)); + } + fieldOffsets[count] = offset; + return offset; + } + + private int parseMethods(int offset, int count) throws InvalidClassFileException { + methodOffsets = new int[count + 1]; + for (int i = 0; i < count; i++) { + methodOffsets[i] = offset; + checkLength(offset, 8); + offset = skipAttributes(offset + 8, getUShort(offset + 6)); + } + methodOffsets[count] = offset; + return offset; + } + + /** + * @return the raw class data bytes + */ + public byte[] getBytes() { + return bytes; + } + + /** + * @return the magic number at the start of the class file. + */ + public int getMagic() { + return getInt(0); + } + + /** + * @return the minor version of the class file + */ + public int getMinorVersion() { + return getUShort(4); + } + + /** + * @return the major version of the class file + */ + public int getMajorVersion() { + return getUShort(6); + } + + /** + * @return the access flags for the class + */ + public int getAccessFlags() { + return getUShort(classInfoOffset); + } + + /** + * @return the index of the constant pool entry for the class name + */ + public int getNameIndex() { + return getUShort(classInfoOffset + 2); + } + + String getClassFromAddress(int addr) throws InvalidClassFileException { + int c = getUShort(addr); + if (c == 0) { + return null; + } else { + try { + return cpParser.getCPClass(c); + } catch (IllegalArgumentException ex) { + throw new InvalidClassFileException(addr, "Invalid class constant pool index: " + c); + } + } + } + + /** + * @return the name of the class in JVM format (e.g., java/lang/Object) + */ + public String getName() throws InvalidClassFileException { + String s = getClassFromAddress(classInfoOffset + 2); + if (s == null) { + throw new InvalidClassFileException(classInfoOffset + 2, "Null class name not allowed"); + } else { + return s; + } + } + + /** + * @return the constant pool index of the superclass name, or 0 if this is + * java.lang.Object + */ + public int getSuperNameIndex() { + return getUShort(classInfoOffset + 4); + } + + /** + * @return the superclass name in JVM format (e.g., java/lang/Object), or null + * if this class is java.lang.Object + */ + public String getSuperName() throws InvalidClassFileException { + return getClassFromAddress(classInfoOffset + 4); + } + + /** + * @return the number of interfaces this class implements + */ + public int getInterfaceCount() { + return interfaceCount; + } + + private void verifyInterfaceIndex(int i) { + if (i < 0 || i >= interfaceCount) { + throw new IllegalArgumentException("Invalid interface index: " + i); + } + } + + /** + * @return the constant pool index of the name of the i'th implemented + * interface + */ + public int getInterfaceNameIndex(int i) { + verifyInterfaceIndex(i); + return getUShort(classInfoOffset + 8 + 2 * i); + } + + /** + * @return an array of the constant pool indices for the names of the + * implemented interfaces + */ + public int[] getInterfaceNameIndices() { + int[] indices = new int[interfaceCount]; + for (int i = 0; i < interfaceCount; i++) { + indices[i] = getUShort(classInfoOffset + 8 + 2 * i); + } + return indices; + } + + /** + * @return the name of the i'th implemented interface + */ + public String getInterfaceName(int i) throws InvalidClassFileException { + verifyInterfaceIndex(i); + String s = getClassFromAddress(classInfoOffset + 8 + 2 * i); + if (s == null) { + throw new InvalidClassFileException(classInfoOffset + 8 + 2 * i, "Null interface name not allowed"); + } else { + return s; + } + } + + /** + * @return an array of the names of the implemented interfaces + */ + public String[] getInterfaceNames() throws InvalidClassFileException { + String[] names = new String[interfaceCount]; + for (int i = 0; i < interfaceCount; i++) { + String s = getClassFromAddress(classInfoOffset + 8 + 2 * i); + if (s == null) { + throw new InvalidClassFileException(classInfoOffset + 8 + 2 * i, "Null interface name not allowed"); + } + names[i] = s; + } + return names; + } + + /** + * This method allows direct read-only access to the constant pool for the + * class. + * + * @return the constant pool for the class + */ + public ConstantPoolParser getCP() { + return cpParser; + } + + /** + * @return the signed 32-bit value at offset i in the class data + */ + public int getInt(int i) { + return (bytes[i] << 24) + ((bytes[i + 1] & 0xFF) << 16) + ((bytes[i + 2] & 0xFF) << 8) + (bytes[i + 3] & 0xFF); + } + + /** + * @return the unsigned 16-bit value at offset i in the class data + */ + public int getUShort(int i) { + return ((bytes[i] & 0xFF) << 8) + (bytes[i + 1] & 0xFF); + } + + /** + * @return the signed 16-bit value at offset i in the class data + */ + public int getShort(int i) { + return (bytes[i] << 8) + (bytes[i + 1] & 0xFF); + } + + /** + * @return the signed 8-bit value at offset i in the class data + */ + public byte getByte(int i) { + return bytes[i]; + } + + /** + * @return the number of fields in the class + */ + public int getFieldCount() { + return fieldOffsets.length - 1; + } + + private void verifyFieldIndex(int f) { + if (f < 0 || f >= fieldOffsets.length - 1) { + throw new IllegalArgumentException("Invalid field index: " + f); + } + } + + /** + * @return the access flags for the f'th field + */ + public int getFieldAccessFlags(int f) { + verifyFieldIndex(f); + return getUShort(fieldOffsets[f]); + } + + String getUtf8FromAddress(int addr) throws InvalidClassFileException { + int s = getUShort(addr); + if (s == 0) { + return null; + } else { + try { + return cpParser.getCPUtf8(s); + } catch (IllegalArgumentException ex) { + throw new InvalidClassFileException(addr, "Invalid Utf8 constant pool index: " + s); + } + } + } + + /** + * @return the name of the f'th field + */ + public String getFieldName(int f) throws InvalidClassFileException { + verifyFieldIndex(f); + return getUtf8FromAddress(fieldOffsets[f] + 2); + } + + /** + * @return the type of the f'th field, in JVM format (e.g., I, Z, + * java/lang/Object) + */ + public String getFieldType(int f) throws InvalidClassFileException { + verifyFieldIndex(f); + return getUtf8FromAddress(fieldOffsets[f] + 4); + } + + /** + * @return the index of the constant pool entry for the name of the f'th + * field, in JVM format (e.g., I, Z, Ljava/lang/Object;) + */ + public int getFieldNameIndex(int f) { + verifyFieldIndex(f); + return getUShort(fieldOffsets[f] + 2); + } + + /** + * @return the index of the constant pool entry for the type of the f'th + * field, in JVM format (e.g., I, Z, Ljava/lang/Object;) + */ + public int getFieldTypeIndex(int f) { + verifyFieldIndex(f); + return getUShort(fieldOffsets[f] + 4); + } + + /** + * AttrIterator provides access to attributes in the class file. + * + * AttrIterators can be reused for many different iterations, like this: + * + *
                              +   *   AttrIterator iter = new AttrIterator();
                              +   *    int fieldCount = reader.getFieldCount();
                              +   *    for (int i = 0; i < fieldCount; i++) {
                              +   *      reader.initFieldAttributeIterator(i, iter);
                              +   *      for (; iter.isValid(); iter.advance()) {
                              +   *        if (iter.getName().equals("ConstantValue")) {
                              +   *          ConstantValueReader cv = new ConstantValueReader(iter);
                              +   *          ...
                              +   *        }
                              +   *      }
                              +   *    }
                              +   * 
                              + */ + public static final class AttrIterator { + ClassReader cr; + int offset; + int size; + private int remaining; + + /** + * Create a blank iterator. The iterator is not valid until it is + * initialized by some other class. + */ + public AttrIterator() { + } + + private void setSize() { + if (remaining > 0) { + size = 6 + cr.getInt(offset + 2); + } + } + + void init(ClassReader cr, int offset) { + this.cr = cr; + this.offset = offset + 2; + this.remaining = cr.getUShort(offset); + setSize(); + } + + void verifyValid() { + if (remaining <= 0) { + throw new IllegalArgumentException("Attempt to manipulate invalid AttrIterator"); + } + } + + public ClassReader getClassReader() { + verifyValid(); + return cr; + } + + /** + * The attribute iterator must be valid. + * + * @return the offset of the raw attribute data (including attribute header) + * in the class file data + */ + public int getRawOffset() { + verifyValid(); + return offset; + } + + /** + * The attribute iterator must be valid. + * + * @return the size of the raw attribute data (including attribute header) + * in the class file data + */ + public int getRawSize() { + verifyValid(); + return size; + } + + /** + * The attribute iterator must be valid. + * + * @return the offset of the attribute data (excluding attribute header) in + * the class file data + */ + public int getDataOffset() { + verifyValid(); + return offset + 6; + } + + /** + * The attribute iterator must be valid. + * + * @return the size of the attribute data (excluding attribute header) in + * the class file data + */ + public int getDataSize() { + verifyValid(); + return size - 6; + } + + /** + * @return the number of attributes left in the list, including this + * attribute (if valid) + */ + public int getRemainingAttributesCount() { + return remaining; + } + + /** + * The attribute iterator must be valid. + * + * @return the constant pool index of the name of the attribute + */ + public int getNameIndex() { + verifyValid(); + return cr.getUShort(offset); + } + + /** + * The attribute iterator must be valid. + * + * @return the name of the attribute + */ + public String getName() throws InvalidClassFileException { + verifyValid(); + String s = cr.getUtf8FromAddress(offset); + if (s == null) { + throw new InvalidClassFileException(offset, "Null attribute name"); + } else { + return s; + } + } + + /** + * @return whether this iterator is valid + */ + public boolean isValid() { + return remaining > 0; + } + + /** + * The attribute iterator must be valid. + * + * The iterator is advanced to the next attribute (which might not exist, so + * the iterator might become invalid). + */ + public void advance() { + verifyValid(); + offset += size; + remaining--; + setSize(); + } + } + + /** + * Point iter at the list of attributes for field f. + */ + public void initFieldAttributeIterator(int f, AttrIterator iter) { + verifyFieldIndex(f); + iter.init(this, fieldOffsets[f] + 6); + } + + /** + * @return the offset of the raw class data for field f + */ + public int getFieldRawOffset(int f) { + verifyFieldIndex(f); + return fieldOffsets[f]; + } + + /** + * @return the size of the raw class data for field f + */ + public int getFieldRawSize(int f) { + verifyFieldIndex(f); + return fieldOffsets[f + 1] - fieldOffsets[f]; + } + + /** + * @return the number of methods in the class + */ + public int getMethodCount() { + return methodOffsets.length - 1; + } + + private void verifyMethodIndex(int m) { + if (m < 0 || m >= methodOffsets.length - 1) { + throw new IllegalArgumentException("Invalid method index: " + m); + } + } + + /** + * @return the offset of the raw class data for method m + */ + public int getMethodRawOffset(int m) { + verifyMethodIndex(m); + return methodOffsets[m]; + } + + /** + * @return the size of the raw class data for method m + */ + public int getMethodRawSize(int m) { + verifyMethodIndex(m); + return methodOffsets[m + 1] - methodOffsets[m]; + } + + /** + * @return the access flags for method m + */ + public int getMethodAccessFlags(int m) { + verifyMethodIndex(m); + return getUShort(methodOffsets[m]); + } + + /** + * @return the name of method m + */ + public String getMethodName(int m) throws InvalidClassFileException { + verifyMethodIndex(m); + return getUtf8FromAddress(methodOffsets[m] + 2); + } + + /** + * @return the method descriptor of method m in JVM format (e.g., + * V(ILjava/lang/Object;) ) + */ + public String getMethodType(int m) throws InvalidClassFileException { + verifyMethodIndex(m); + return getUtf8FromAddress(methodOffsets[m] + 4); + } + + /** + * @return the constant pool index of the name of method m + */ + public int getMethodNameIndex(int m) { + verifyMethodIndex(m); + return getUShort(methodOffsets[m] + 2); + } + + /** + * @return the constant pool index of the method descriptor of method m + */ + public int getMethodTypeIndex(int m) { + verifyMethodIndex(m); + return getUShort(methodOffsets[m] + 4); + } + + /** + * Point iter at the list of attributes for method m. + */ + public void initMethodAttributeIterator(int m, AttrIterator iter) { + verifyMethodIndex(m); + iter.init(this, methodOffsets[m] + 6); + } + + /** + * Point iter at the list of attributes for the class. + */ + public void initClassAttributeIterator(AttrIterator iter) { + iter.init(this, attrInfoOffset); + } +} diff --git a/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeCT/ClassReaderAttribute.java b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeCT/ClassReaderAttribute.java new file mode 100644 index 000000000..fe8408728 --- /dev/null +++ b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeCT/ClassReaderAttribute.java @@ -0,0 +1,91 @@ +/******************************************************************************* + * 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.shrikeCT; + +/** + * This is a base class for "attribute readers", the classes which provide + * access to the contents of attributes. + */ +public abstract class ClassReaderAttribute { + protected ClassReader cr; + protected int attr; + protected int length; + + /** + * Construct a reader for a particular attribute. + * + * @param attr + * a valid attribute iterator pointing at the attribute to read + * @param expectedName + * the name the attribute must have + */ + protected ClassReaderAttribute(ClassReader.AttrIterator attr, String expectedName) throws InvalidClassFileException { + attr.verifyValid(); + this.cr = attr.cr; + this.attr = attr.offset; + this.length = attr.size; + + String n = attr.getName(); + if (expectedName != n && !expectedName.equals(n)) { + throw new IllegalArgumentException("Attribute " + n + " is not a " + expectedName + " attribute"); + } + } + + /** + * @return the class reader the attribute belongs to + */ + public final ClassReader getClassReader() { + return cr; + } + + /** + * @return the offset of the raw attribute data (including the attribute + * header) + */ + public final int getRawOffset() { + return attr; + } + + /** + * @return the size of the raw attribute data (including the attribute header) + */ + public final int getRawSize() { + return length; + } + + /** + * Ensure that the len bytes starting at offset fall within the attribute + * data. + * + * @throws InvalidClassFileException + * if the bytes fall outside the data + */ + protected final void checkSize(int offset, int len) throws InvalidClassFileException { + if (length < offset - attr + len) { + throw new InvalidClassFileException(offset, "Attribute data too short, expected " + len + " bytes, got " + + (length + attr - offset)); + } + } + + /** + * Ensure that the len bytes starting at offset end at the end of the + * attribute data. + * + * @throws InvalidClassFileException + * if the bytes do not end at the end of the attribute + */ + protected final void checkSizeEquals(int offset, int len) throws InvalidClassFileException { + if (length != offset - attr + len) { + throw new InvalidClassFileException(offset, "Attribute data invalid length, expected " + len + " bytes, got " + + (length + attr - offset)); + } + } +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeCT/ClassWriter.java b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeCT/ClassWriter.java new file mode 100644 index 000000000..254992e53 --- /dev/null +++ b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeCT/ClassWriter.java @@ -0,0 +1,931 @@ +/******************************************************************************* + * 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.shrikeCT; + +import java.util.ArrayList; +import java.util.HashMap; + +/** + * This class formats and writes class data into JVM format. + */ +public final class ClassWriter implements ClassConstants { + // input + private int majorVersion = 46; + private int minorVersion = 0; + private ConstantPoolParser rawCP; + private HashMap cachedCPEntries = new HashMap(1); + private ArrayList newCPEntries = new ArrayList(1); + private int nextCPIndex = 1; + private ArrayList fields = new ArrayList(1); + private ArrayList methods = new ArrayList(1); + private ArrayList classAttributes = new ArrayList(1); + private int thisClass; + private int superClass; + private int[] superInterfaces; + private int accessFlags; + private boolean forceAddCPEntries = false; + + // output + private byte[] buf; + private int bufLen; + + /** + * Create a blank ClassWriter with no methods, fields, or attributes, an empty + * constant pool, no super class, no implemented interfaces, no name, + * majorVersion 46, and minorVersion 0. + */ + public ClassWriter() { + } + + /** + * Set the class file format major version. You probably don't want to use + * this unless you really know what you are doing. + */ + public void setMajorVersion(int major) { + if (major < 0 || major > 0xFFFF) { + throw new IllegalArgumentException("Major version out of range: " + major); + } + majorVersion = major; + } + + /** + * Set the class file format minor version. You probably don't want to use + * this unless you really know what you are doing. + */ + public void setMinorVersion(int minor) { + if (minor < 0 || minor > 0xFFFF) { + throw new IllegalArgumentException("Major version out of range: " + minor); + } + minorVersion = minor; + } + + static abstract class CWItem { + abstract byte getType(); + } + + static class CWString extends CWItem { + private String s; + + CWString(String s) { + this.s = s; + } + + public boolean equals(Object o) { + return o instanceof CWString && ((CWString) o).s.equals(s); + } + + public int hashCode() { + return s.hashCode() + 3901; + } + + byte getType() { + return CONSTANT_String; + } + } + + static class CWClass extends CWItem { + private String c; + + CWClass(String c) { + this.c = c; + } + + public boolean equals(Object o) { + return o instanceof CWClass && ((CWClass) o).c.equals(c); + } + + public int hashCode() { + return c.hashCode() + 1431; + } + + byte getType() { + return CONSTANT_Class; + } + } + + static class CWRef extends CWItem { + private String c; + private String n; + private String t; + private byte type; + + CWRef(byte type, String c, String n, String t) { + this.type = type; + this.c = c; + this.n = n; + this.t = t; + } + + public boolean equals(Object o) { + if (o instanceof CWRef) { + CWRef r = (CWRef) o; + return r.type == type && r.c.equals(c) && r.n.equals(n) && r.t.equals(t); + } else { + return false; + } + } + + public int hashCode() { + return type + (c.hashCode() << 5) + (n.hashCode() << 3) + t.hashCode(); + } + + byte getType() { + return type; + } + } + + static class CWNAT extends CWItem { + private String n; + private String t; + + CWNAT(String n, String t) { + this.n = n; + this.t = t; + } + + public boolean equals(Object o) { + if (o instanceof CWNAT) { + CWNAT r = (CWNAT) o; + return r.n.equals(n) && r.t.equals(t); + } else { + return false; + } + } + + public int hashCode() { + return (n.hashCode() << 3) + t.hashCode(); + } + + byte getType() { + return CONSTANT_NameAndType; + } + } + + /** + * Copy a constant pool from some ClassReader into this class. This must be + * done before any entries are allocated in this ClassWriter's constant pool, + * and it can only be done once. If and only if this is done, it is safe to + * copy "raw" fields, methods and attributes from the ClassReader into this + * class, because the constant pool references in those fields, methods and + * attributes are guaranteed to point to the same constant pool items in this + * new class. + * + * @param cacheEntries + * records whether to parse the raw constant pool completely so that + * if new entries are required which are the same as entries already + * in the raw pool, the existing entries in the raw pool are used + * instead. Setting this to 'true' produces smaller constant pools + * but may slow down performance because the raw pool must be + * completely parsed + */ + public void setRawCP(ConstantPoolParser cp, boolean cacheEntries) throws InvalidClassFileException { + if (rawCP != null) { + throw new IllegalArgumentException("Cannot set raw constant pool twice"); + } + if (nextCPIndex != 1) { + throw new IllegalArgumentException("Cannot set raw constant pool after allocating new entries"); + } + rawCP = cp; + nextCPIndex = cp.getItemCount(); + + if (cacheEntries) { + for (int i = 1; i < nextCPIndex; i++) { + byte t = cp.getItemType(i); + switch (t) { + case CONSTANT_String: + cachedCPEntries.put(new CWString(cp.getCPString(i)), new Integer(i)); + break; + case CONSTANT_Class: + cachedCPEntries.put(new CWClass(cp.getCPClass(i)), new Integer(i)); + break; + case CONSTANT_FieldRef: + case CONSTANT_InterfaceMethodRef: + case CONSTANT_MethodRef: + cachedCPEntries.put(new CWRef(t, cp.getCPRefClass(i), cp.getCPRefName(i), cp.getCPRefType(i)), new Integer(i)); + break; + case CONSTANT_NameAndType: + cachedCPEntries.put(new CWNAT(cp.getCPNATName(i), cp.getCPNATType(i)), new Integer(i)); + break; + case CONSTANT_Integer: + cachedCPEntries.put(new Integer(cp.getCPInt(i)), new Integer(i)); + break; + case CONSTANT_Float: + cachedCPEntries.put(new Float(cp.getCPFloat(i)), new Integer(i)); + break; + case CONSTANT_Long: + cachedCPEntries.put(new Long(cp.getCPLong(i)), new Integer(i)); + break; + case CONSTANT_Double: + cachedCPEntries.put(new Double(cp.getCPDouble(i)), new Integer(i)); + break; + case CONSTANT_Utf8: + cachedCPEntries.put(cp.getCPUtf8(i), new Integer(i)); + break; + } + } + } + } + + /** + * @param force + * true iff you want the addCP methods to always create a new + * constant pool entry and never reuse an existing constant pool + * entry + */ + public void setForceAddCPEntries(boolean force) { + forceAddCPEntries = force; + } + + private int addCPEntry(Object o, int size) { + if (cachedCPEntries == null) { + throw new IllegalArgumentException("Cannot add a new constant pool entry during makeBytes() processing!"); + } + + Integer i = forceAddCPEntries ? null : cachedCPEntries.get(o); + if (i != null) { + return i.intValue(); + } else { + int index = nextCPIndex; + nextCPIndex += size; + i = new Integer(index); + cachedCPEntries.put(o, i); + newCPEntries.add(o); + if (nextCPIndex > 0xFFFF) { + throw new IllegalArgumentException("Constant pool item count exceeded"); + } + return index; + } + } + + /** + * Add a Utf8 string to the constant pool if necessary. + * + * @return the index of a constant pool item with the right value + */ + public int addCPUtf8(String s) { + return addCPEntry(s, 1); + } + + /** + * Add an Integer to the constant pool if necessary. + * + * @return the index of a constant pool item with the right value + */ + public int addCPInt(int i) { + return addCPEntry(new Integer(i), 1); + } + + /** + * Add a Float to the constant pool if necessary. + * + * @return the index of a constant pool item with the right value + */ + public int addCPFloat(float f) { + return addCPEntry(new Float(f), 1); + } + + /** + * Add a Long to the constant pool if necessary. + * + * @return the index of a constant pool item with the right value + */ + public int addCPLong(long l) { + return addCPEntry(new Long(l), 2); + } + + /** + * Add a Double to the constant pool if necessary. + * + * @return the index of a constant pool item with the right value + */ + public int addCPDouble(double d) { + return addCPEntry(new Double(d), 2); + } + + /** + * Add a String to the constant pool if necessary. + * + * @return the index of a constant pool item with the right value + */ + public int addCPString(String s) { + return addCPEntry(new CWString(s), 1); + } + + /** + * Add a Class to the constant pool if necessary. + * + * @param s + * the class name, in JVM format (e.g., java/lang/Object) + * @return the index of a constant pool item with the right value + */ + public int addCPClass(String s) { + return addCPEntry(new CWClass(s), 1); + } + + /** + * Add a FieldRef to the constant pool if necessary. + * + * @param c + * the class name, in JVM format (e.g., java/lang/Object) + * @param n + * the field name + * @param t + * the field type, in JVM format (e.g., I, Z, or Ljava/lang/Object;) + * @return the index of a constant pool item with the right value + */ + public int addCPFieldRef(String c, String n, String t) { + return addCPEntry(new CWRef(CONSTANT_FieldRef, c, n, t), 1); + } + + /** + * Add a MethodRef to the constant pool if necessary. + * + * @param c + * the class name, in JVM format (e.g., java/lang/Object) + * @param n + * the method name + * @param t + * the method type, in JVM format (e.g., V(ILjava/lang/Object;) ) + * @return the index of a constant pool item with the right value + */ + public int addCPMethodRef(String c, String n, String t) { + return addCPEntry(new CWRef(CONSTANT_MethodRef, c, n, t), 1); + } + + /** + * Add an InterfaceMethodRef to the constant pool if necessary. + * + * @param c + * the class name, in JVM format (e.g., java/lang/Object) + * @param n + * the field name + * @param t + * the method type, in JVM format (e.g., V(ILjava/lang/Object;) ) + * @return the index of a constant pool item with the right value + */ + public int addCPInterfaceMethodRef(String c, String n, String t) { + return addCPEntry(new CWRef(CONSTANT_InterfaceMethodRef, c, n, t), 1); + } + + /** + * Add a NameAndType to the constant pool if necessary. + * + * @param n + * the name + * @param t + * the type, in JVM format + * @return the index of a constant pool item with the right value + */ + public int addCPNAT(String n, String t) { + return addCPEntry(new CWNAT(n, t), 1); + } + + /** + * Set the access flags for the class. + */ + public void setAccessFlags(int f) { + if (f < 0 || f > 0xFFFF) { + throw new IllegalArgumentException("Access flags out of range: " + f); + } + accessFlags = f; + } + + /** + * Set the constant pool index for the name of the class. + */ + public void setNameIndex(int c) { + if (c < 1 || c > 0xFFFF) { + throw new IllegalArgumentException("Class name index out of range: " + c); + } + thisClass = c; + } + + /** + * Set the constant pool index for the name of the superclass. + */ + public void setSuperNameIndex(int c) { + if (c < 0 || c > 0xFFFF) { + throw new IllegalArgumentException("Superclass name index out of range: " + c); + } + superClass = c; + } + + /** + * Set the constant pool indices for the names of the implemented interfaces. + */ + public void setInterfaceNameIndices(int[] ifaces) { + if (ifaces != null) { + if (ifaces.length > 0xFFFF) { + throw new IllegalArgumentException("Too many interfaces implemented: " + ifaces.length); + } + for (int i = 0; i < ifaces.length; i++) { + int c = ifaces[i]; + if (c < 1 || c > 0xFFFF) { + throw new IllegalArgumentException("Interface name index out of range: " + c); + } + } + } + superInterfaces = ifaces; + } + + /** + * Set the name of the class. + */ + public void setName(String c) { + setNameIndex(addCPClass(c)); + } + + /** + * Set the name of the superclass; if c is null, then there is no superclass + * (this must be java/lang/Object). + */ + public void setSuperName(String c) { + setSuperNameIndex(c == null ? 0 : addCPClass(c)); + } + + /** + * Set the names of the implemented interfaces. + */ + public void setInterfaceNames(String[] ifaces) { + if (ifaces == null) { + setInterfaceNameIndices((int[]) null); + } else { + int[] ifs = new int[ifaces.length]; + for (int i = 0; i < ifaces.length; i++) { + ifs[i] = addCPClass(ifaces[i]); + } + setInterfaceNameIndices(ifs); + } + } + + /** + * An Element is an object that can be serialized into a byte buffer. + * Serialization via 'copyInto' is performed when the user calls makeBytes() + * on the ClassWriter. At this time no new constant pool items can be + * allocated, so any item indices that need to be emitted must be allocated + * earlier. + */ + public static abstract class Element { + public Element() { + } + + /** + * @return the number of bytes that will be generated. + */ + public abstract int getSize(); + + /** + * Copy the bytes into 'buf' at offset 'offset'. + * + * @return the number of bytes copies, which must be equal to getSize() + */ + public abstract int copyInto(byte[] buf, int offset); + } + + /** + * A RawElement is an Element that is already available as some chunk of a + * byte buffer. + */ + public static final class RawElement extends Element { + private byte[] buf; + private int offset; + private int len; + + /** + * Create an Element for the 'len' bytes in 'buf' at offset 'offset'. + */ + public RawElement(byte[] buf, int offset, int len) { + this.buf = buf; + this.offset = offset; + this.len = len; + } + + public int getSize() { + return len; + } + + public int copyInto(byte[] dest, int destOffset) { + System.arraycopy(buf, offset, dest, destOffset, len); + return destOffset + len; + } + } + + /** + * Add a method to the class, the method data given as "raw" bytes (probably + * obtained from a ClassReader). + */ + public void addRawMethod(Element e) { + methods.add(e); + } + + /** + * Add a field to the class, the field data given as "raw" bytes (probably + * obtained from a ClassReader). + */ + public void addRawField(Element e) { + fields.add(e); + } + + /** + * Add a method to the class. + * + * @param access + * the access flags + * @param name + * the method name + * @param type + * the method type in JVM format (e.g., V(ILjava/lang/Object;) ) + * @param attributes + * the attributes in raw form, one Element per attribute + */ + public void addMethod(int access, String name, String type, Element[] attributes) { + addMethod(access, addCPUtf8(name), addCPUtf8(type), attributes); + } + + /** + * Add a field to the class. + * + * @param access + * the access flags + * @param name + * the field name + * @param type + * the field type in JVM format (e.g., I, Z, Ljava/lang/Object;) + * @param attributes + * the attributes in raw form, one Element per attribute + */ + public void addField(int access, String name, String type, Element[] attributes) { + addField(access, addCPUtf8(name), addCPUtf8(type), attributes); + } + + static final class MemberElement extends Element { + private int access; + private int name; + private int type; + private Element[] attributes; + + public MemberElement(int access, int name, int type, Element[] attributes) { + if (access < 0 || access > 0xFFFF) { + throw new IllegalArgumentException("Access flags out of range: " + access); + } + if (name < 1 || name > 0xFFFF) { + throw new IllegalArgumentException("Name constant pool index out of range: " + name); + } + if (type < 1 || type > 0xFFFF) { + throw new IllegalArgumentException("Type constant pool index out of range: " + name); + } + if (attributes.length > 0xFFFF) { + throw new IllegalArgumentException("Too many attributes: " + attributes.length); + } + + this.access = access; + this.name = name; + this.type = type; + this.attributes = attributes; + } + + public int getSize() { + int size = 8; + if (attributes != null) { + for (int i = 0; i < attributes.length; i++) { + size += attributes[i].getSize(); + } + } + return size; + } + + public int copyInto(byte[] buf, int offset) { + setUShort(buf, offset, access); + setUShort(buf, offset + 2, name); + setUShort(buf, offset + 4, type); + if (attributes != null) { + setUShort(buf, offset + 6, attributes.length); + offset += 8; + for (int i = 0; i < attributes.length; i++) { + offset = attributes[i].copyInto(buf, offset); + } + } else { + setUShort(buf, offset + 6, 0); + offset += 8; + } + return offset; + } + } + + /** + * Add a method to the class. + * + * @param access + * the access flags + * @param name + * the constant pool index of the method name + * @param type + * the constant pool index of the method type in JVM format (e.g., + * V(ILjava/lang/Object;) ) + * @param attributes + * the attributes in raw form, one Element per attribute + */ + public void addMethod(int access, int name, int type, Element[] attributes) { + //int idx=methods.size()-2; + //if (idx<0) idx=0; + //methods.add(0,new MemberElement(access, name, type, attributes)); + methods.add(new MemberElement(access, name, type, attributes)); + if (methods.size() > 0xFFFF) { + throw new IllegalArgumentException("Too many methods"); + } + } + + /** + * Add a field to the class. + * + * @param access + * the access flags + * @param name + * the constant pool index of the field name + * @param type + * the constant pool index of the field type in JVM format (e.g., I, + * Z, Ljava/lang/Object;) + * @param attributes + * the attributes in raw form, one Element per attribute + */ + public void addField(int access, int name, int type, Element[] attributes) { + fields.add(new MemberElement(access, name, type, attributes)); + if (fields.size() > 0xFFFF) { + throw new IllegalArgumentException("Too many fields"); + } + } + + /** + * Add an atttribute to the class. + * + * @param attribute + * the attribute in raw form + */ + public void addClassAttribute(Element attribute) { + classAttributes.add(attribute); + if (classAttributes.size() > 0xFFFF) { + throw new IllegalArgumentException("Too many class attributes: " + classAttributes.size()); + } + } + + private int reserveBuf(int size) { + if (buf == null) { + buf = new byte[size]; + } else if (bufLen + size > buf.length) { + byte[] newBuf = new byte[Math.max(buf.length * 2, bufLen + size)]; + System.arraycopy(buf, 0, newBuf, 0, bufLen); + buf = newBuf; + } + int offset = bufLen; + bufLen += size; + return offset; + } + + private void emitElement(Element e) { + int size = e.getSize(); + int offset = reserveBuf(size); + int finalOffset = e.copyInto(buf, offset); + if (finalOffset - offset != size) { + throw new Error("Element failed to output the promised bytes: promised " + size + ", got " + (finalOffset - offset)); + } + } + + private static final char[] noChars = new char[0]; + + private void emitConstantPool() { + if (rawCP != null) { + int len = rawCP.getRawSize(); + int offset = reserveBuf(len); + System.arraycopy(rawCP.getRawBytes(), rawCP.getRawOffset(), buf, offset, len); + } + + char[] chars = noChars; + + // BE CAREFUL: the newCPEntries array grows during this loop. + for (int i = 0; i < newCPEntries.size(); i++) { + Object o = newCPEntries.get(i); + if (o instanceof CWItem) { + CWItem item = (CWItem) o; + byte t = item.getType(); + int offset; + switch (t) { + case CONSTANT_Class: + offset = reserveBuf(3); + setUShort(buf, offset + 1, addCPUtf8(((CWClass) item).c)); + break; + case CONSTANT_String: + offset = reserveBuf(3); + setUShort(buf, offset + 1, addCPUtf8(((CWString) item).s)); + break; + case CONSTANT_NameAndType: { + offset = reserveBuf(5); + CWNAT nat = (CWNAT) item; + setUShort(buf, offset + 1, addCPUtf8(nat.n)); + setUShort(buf, offset + 3, addCPUtf8(nat.t)); + break; + } + case CONSTANT_MethodRef: + case CONSTANT_FieldRef: + case CONSTANT_InterfaceMethodRef: { + offset = reserveBuf(5); + CWRef ref = (CWRef) item; + setUShort(buf, offset + 1, addCPClass(ref.c)); + setUShort(buf, offset + 3, addCPNAT(ref.n, ref.t)); + break; + } + default: + throw new Error("Invalid type: " + t); + } + buf[offset] = t; + } else { + if (o instanceof String) { + String s = (String) o; + int slen = s.length(); + + if (chars.length < slen) { + chars = new char[slen]; + } + s.getChars(0, slen, chars, 0); + + int offset = reserveBuf(3); + buf[offset] = CONSTANT_Utf8; + + int maxBytes = slen * 3; + int p = reserveBuf(maxBytes); // worst case reservation + + for (int j = 0; j < slen; j++) { + char ch = chars[j]; + if (ch == 0) { + setUShort(buf, p, 0xC080); + p += 2; + } else if (ch < 0x80) { + buf[p] = (byte) ch; + p += 1; + } else if (ch < 0x800) { + buf[p] = (byte) ((ch >> 6) | 0xC0); + buf[p + 1] = (byte) ((ch & 0x3F) | 0x80); + p += 2; + } else { + buf[p] = (byte) ((ch >> 12) | 0xE0); + buf[p + 1] = (byte) (((ch >> 6) & 0x3F) | 0x80); + buf[p + 2] = (byte) ((ch & 0x3F) | 0x80); + p += 3; + } + } + int bytes = p - (offset + 3); + reserveBuf(bytes - maxBytes); // negative reservation to push back buf + // size + if (bytes > 0xFFFF) { + throw new IllegalArgumentException("String too long: " + bytes + " bytes"); + } + setUShort(buf, offset + 1, bytes); + } else if (o instanceof Integer) { + int offset = reserveBuf(5); + buf[offset] = CONSTANT_Integer; + setInt(buf, offset + 1, ((Integer) o).intValue()); + } else if (o instanceof Long) { + int offset = reserveBuf(9); + buf[offset] = CONSTANT_Long; + setLong(buf, offset + 1, ((Long) o).longValue()); + } else if (o instanceof Float) { + int offset = reserveBuf(5); + buf[offset] = CONSTANT_Float; + setFloat(buf, offset + 1, ((Float) o).intValue()); + } else if (o instanceof Double) { + int offset = reserveBuf(9); + buf[offset] = CONSTANT_Double; + setDouble(buf, offset + 1, ((Double) o).intValue()); + } + } + } + } + + /** + * After you've added everything you need to the class, call this method to + * generate the actual class file data. This can only be called once. + */ + public byte[] makeBytes() { + if (buf != null) { + throw new IllegalArgumentException("Can't call makeBytes() twice"); + } + + if (thisClass == 0) { + throw new IllegalArgumentException("No class name set"); + } + + reserveBuf(10); + setInt(buf, 0, MAGIC); + setUShort(buf, 4, minorVersion); + setUShort(buf, 6, majorVersion); + + emitConstantPool(); + // The constant pool can grow during emmission, so store the size last + setUShort(buf, 8, nextCPIndex); + // No new constant pool entries can be allocated; make sure we + // catch any such error by client code + cachedCPEntries = null; + + int offset = reserveBuf(8); + setUShort(buf, offset, accessFlags); + setUShort(buf, offset + 2, thisClass); + setUShort(buf, offset + 4, superClass); + if (superInterfaces != null) { + setUShort(buf, offset + 6, superInterfaces.length); + reserveBuf(superInterfaces.length * 2); + for (int i = 0; i < superInterfaces.length; i++) { + setUShort(buf, offset + 8 + i * 2, superInterfaces[i]); + } + } else { + setUShort(buf, offset + 6, 0); + } + + offset = reserveBuf(2); + int numFields = fields.size(); + setUShort(buf, offset, numFields); + for (int i = 0; i < numFields; i++) { + emitElement(fields.get(i)); + } + + offset = reserveBuf(2); + int numMethods = methods.size(); + //Xiangyu, debug + //System.out.println("numMethods="+numMethods); + setUShort(buf, offset, numMethods); + for (int i = 0; i < numMethods; i++) { + emitElement(methods.get(i)); + } + + offset = reserveBuf(2); + int numAttrs = classAttributes.size(); + setUShort(buf, offset, numAttrs); + for (int i = 0; i < numAttrs; i++) { + emitElement(classAttributes.get(i)); + } + + if (buf.length == bufLen) { + return buf; + } else { + byte[] b = new byte[bufLen]; + System.arraycopy(buf, 0, b, 0, bufLen); + return b; + } + } + + /** + * Set the byte at offset 'offset' in 'buf' to the unsigned 8-bit value in v. + */ + public static void setUByte(byte[] buf, int offset, int v) { + buf[offset] = (byte) v; + } + + /** + * Set the 4 bytes at offset 'offset' in 'buf' to the signed 32-bit value in + * v. + */ + public static void setInt(byte[] buf, int offset, int v) { + buf[offset] = (byte) (v >> 24); + buf[offset + 1] = (byte) (v >> 16); + buf[offset + 2] = (byte) (v >> 8); + buf[offset + 3] = (byte) v; + } + + /** + * Set the 8 bytes at offset 'offset' in 'buf' to the signed 64-bit value in + * v. + */ + public static void setLong(byte[] buf, int offset, long v) { + setInt(buf, offset, (int) (v >> 32)); + setInt(buf, offset + 4, (int) v); + } + + /** + * Set the 4 bytes at offset 'offset' in 'buf' to the float value in v. + */ + public static void setFloat(byte[] buf, int offset, float v) { + setInt(buf, offset, Float.floatToIntBits(v)); + } + + /** + * Set the 8 bytes at offset 'offset' in 'buf' to the double value in v. + */ + public static void setDouble(byte[] buf, int offset, double v) { + setLong(buf, offset, Double.doubleToRawLongBits(v)); + } + + /** + * Set the 2 bytes at offset 'offset' in 'buf' to the unsigned 16-bit value in + * v. + */ + public static void setUShort(byte[] buf, int offset, int v) { + buf[offset] = (byte) (v >> 8); + buf[offset + 1] = (byte) v; + } +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeCT/CodeReader.java b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeCT/CodeReader.java new file mode 100644 index 000000000..b9f927ff9 --- /dev/null +++ b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeCT/CodeReader.java @@ -0,0 +1,95 @@ +/******************************************************************************* + * 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.shrikeCT; + +/** + * This attribute reader reads Code attributes from methods. + */ +public final class CodeReader extends ClassReaderAttribute { + private int codeLen; + private int exnTableLen; + + public CodeReader(ClassReader.AttrIterator iter) throws InvalidClassFileException { + super(iter, "Code"); + + int offset = attr + 6; + checkSize(offset, 8); + codeLen = cr.getInt(offset + 4); + offset += 8; + + checkSize(offset, codeLen + 2); + offset += codeLen; + exnTableLen = cr.getUShort(offset); + offset += 2; + checkSize(offset, exnTableLen * 8 + 2); + offset += exnTableLen * 8; + int attrCount = cr.getUShort(offset); + offset += 2; + for (int i = 0; i < attrCount; i++) { + checkSize(offset, 6); + int len = cr.getInt(offset + 2); + offset += 6; + checkSize(offset, len); + offset += len; + } + } + + /** + * @return the maximum stack size used by the code, in words + */ + public int getMaxStack() { + return cr.getUShort(attr + 6); + } + + /** + * @return the maximum local variable size used by the code, in words + */ + public int getMaxLocals() { + return cr.getUShort(attr + 8); + } + + /** + * @return the length of the bytecode array, in bytes + */ + public int getBytecodeLength() { + return codeLen; + } + + /** + * @return the bytecode bytes + */ + public byte[] getBytecode() { + byte[] r = new byte[codeLen]; + System.arraycopy(cr.getBytes(), attr + 14, r, 0, r.length); + return r; + } + + /** + * @return the raw exception handler data, a flattened sequence of (startPC, + * endPC, catchClassIndex, catchPC) tuples + */ + public int[] getRawHandlers() { + int[] r = new int[exnTableLen * 4]; + int offset = attr + 14 + codeLen + 2; + for (int i = 0; i < r.length; i++) { + r[i] = cr.getUShort(offset); + offset += 2; + } + return r; + } + + /** + * Point iter at the list of attributes for this code. + */ + public void initAttributeIterator(ClassReader.AttrIterator iter) { + iter.init(cr, attr + 14 + codeLen + 2 + exnTableLen * 8); + } +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeCT/CodeWriter.java b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeCT/CodeWriter.java new file mode 100644 index 000000000..c9c3b07e0 --- /dev/null +++ b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeCT/CodeWriter.java @@ -0,0 +1,153 @@ +/******************************************************************************* + * 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.shrikeCT; + +/** + * This class helps emit Code elements. + * + * After constructing a CodeWriter, at least the max stack, max locals and + * bytecode bytes must be set before it can be used. + */ +public final class CodeWriter extends ClassWriter.Element { + private int attrID; + private int maxLocals = -1; + private int maxStack = -1; + private byte[] code; + private int[] exnHandlers; + private ClassWriter.Element[] attributes; + + /** + * Build an empty serializable Code attribute. + */ + public CodeWriter(ClassWriter w) { + attrID = w.addCPUtf8("Code"); + } + + private void verify() { + if (maxStack < 0) { + throw new IllegalArgumentException("maxStack not set"); + } + if (maxLocals < 0) { + throw new IllegalArgumentException("maxLocals not set"); + } + if (code == null) { + throw new IllegalArgumentException("No bytecodes set"); + } + } + + //By Xiangyu + public int getCodeLength() { + return code.length; + } + + public int getSize() { + verify(); + + int size = 14 + code.length + 2 + (exnHandlers == null ? 0 : exnHandlers.length) * 2 + 2; + if (attributes != null) { + for (int i = 0; i < attributes.length; i++) { + size += attributes[i].getSize(); + } + } + return size; + } + + public int copyInto(byte[] buf, int offset) { + verify(); + + int start = offset; + ClassWriter.setUShort(buf, offset, attrID); + ClassWriter.setUShort(buf, offset + 6, maxStack); + ClassWriter.setUShort(buf, offset + 8, maxLocals); + ClassWriter.setInt(buf, offset + 10, code.length); + offset += 14; + System.arraycopy(code, 0, buf, offset, code.length); + offset += code.length; + ClassWriter.setUShort(buf, offset, (exnHandlers == null ? 0 : exnHandlers.length) / 4); + offset += 2; + if (exnHandlers != null) { + for (int i = 0; i < exnHandlers.length; i++) { + ClassWriter.setUShort(buf, offset, exnHandlers[i]); + offset += 2; + } + } + + ClassWriter.setUShort(buf, offset, (attributes == null ? 0 : attributes.length)); + offset += 2; + if (attributes != null) { + for (int i = 0; i < attributes.length; i++) { + offset = attributes[i].copyInto(buf, offset); + } + } + ClassWriter.setInt(buf, start + 2, offset - start - 6); + return offset; + } + + /** + * Set the bytecodes for this Code attribute. + */ + public void setCode(byte[] code) { + if (code.length > 0xFFFF) { + throw new IllegalArgumentException("Code array is too long: " + code.length); + } + if (code.length == 0) { + throw new IllegalArgumentException("Code array is empty"); + } + + this.code = code; + } + + /** + * Set the raw handler data for this Code attribute. + * + * @param exnHandlers + * a flattened sequence of (startPC, endPC, catchClassIndex, catchPC) + * tuples + */ + public void setRawHandlers(int[] exnHandlers) { + if (exnHandlers.length % 4 != 0) { + throw new IllegalArgumentException("Exception handlers array has bad length: " + exnHandlers.length); + } + if (exnHandlers.length / 4 > 0xFFFF) { + throw new IllegalArgumentException("Too many exception handlers: " + exnHandlers.length / 4); + } + for (int i = 0; i < exnHandlers.length; i++) { + int v = exnHandlers[i]; + if (v < 0 || v > 0xFFFF) { + throw new IllegalArgumentException("Invalid exception handler entry at " + i); + } + } + + this.exnHandlers = exnHandlers; + } + + /** + * Set the maximum number of local variable space used, in words, by this + * Code. + */ + public void setMaxLocals(int maxLocals) { + this.maxLocals = maxLocals; + } + + /** + * Set the maximum stack size, in words, in this Code. + */ + public void setMaxStack(int maxStack) { + this.maxStack = maxStack; + } + + /** + * Set the attributes of this Code. + */ + public void setAttributes(ClassWriter.Element[] attributes) { + this.attributes = attributes; + } +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeCT/ConstantPoolParser.java b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeCT/ConstantPoolParser.java new file mode 100644 index 000000000..f6845454a --- /dev/null +++ b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeCT/ConstantPoolParser.java @@ -0,0 +1,420 @@ +/******************************************************************************* + * 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.shrikeCT; + +/** + * A ConstantPoolParser provides read-only access to the constant pool of a + * class file. + */ +public final class ConstantPoolParser implements ClassConstants { + private byte[] bytes; + private int[] cpOffsets; + private String[] cpItems; + + /** + * @param bytes + * the raw class file data + * @param offset + * the start of the constant pool data + * @param itemCount + * the number of items in the pool + */ + public ConstantPoolParser(byte[] bytes, int offset, int itemCount) throws InvalidClassFileException { + this.bytes = bytes; + parseConstantPool(offset, itemCount); + } + + /** + * @return the buffer holding the raw class file data + */ + public byte[] getRawBytes() { + return bytes; + } + + /** + * @return the offset of the constant pool data in the raw class file buffer + */ + public int getRawOffset() { + return cpOffsets[1]; + } + + /** + * @return the size of the constant pool data in the raw class file buffer + */ + public int getRawSize() { + return cpOffsets[cpOffsets.length - 1] - cpOffsets[1]; + } + + /** + * @return the number of constant pool items (maximum item index plus one) + */ + public int getItemCount() { + return cpOffsets.length - 1; + } + + private void checkLength(int offset, int required) throws InvalidClassFileException { + if (bytes.length < offset + required) { + throw new InvalidClassFileException(offset, "file truncated, expected " + required + " bytes, saw only " + + (bytes.length - offset)); + } + } + + /** + * @return the type of constant pool item i, or 0 if i is an unused constant + * pool item + */ + public byte getItemType(int i) { + if (i < 1 || i >= cpItems.length) { + throw new IllegalArgumentException("Constant pool item #" + i + " out of range"); + } + int offset = cpOffsets[i]; + if (offset == 0) { + return 0; + } else { + return getByte(offset); + } + } + + /** + * @return the name of the Class at constant pool item i, in JVM format (e.g., + * java/lang/Object) + */ + public String getCPClass(int i) throws InvalidClassFileException { + if (i < 1 || i >= cpItems.length) { + throw new IllegalArgumentException("Constant pool item #" + i + " out of range"); + } + int offset = cpOffsets[i]; + if (offset == 0 || getByte(offset) != CONSTANT_Class) { + throw new IllegalArgumentException("Constant pool item #" + i + " is not a Class"); + } + String s = cpItems[i]; + if (s == null) { + try { + s = getCPUtf8(getUShort(offset + 1)); + } catch (IllegalArgumentException ex) { + throw new InvalidClassFileException(offset, "Invalid class name at constant pool item #" + i + ": " + ex.getMessage()); + } + cpItems[i] = s; + } + return s; + } + + /** + * @return the String at constant pool item i + */ + public String getCPString(int i) throws InvalidClassFileException { + if (i < 1 || i >= cpItems.length) { + throw new IllegalArgumentException("Constant pool item #" + i + " out of range"); + } + int offset = cpOffsets[i]; + if (offset == 0 || getByte(offset) != CONSTANT_String) { + throw new IllegalArgumentException("Constant pool item #" + i + " is not a String"); + } + String s = cpItems[i]; + if (s == null) { + try { + s = getCPUtf8(getUShort(offset + 1)); + } catch (IllegalArgumentException ex) { + throw new InvalidClassFileException(offset, "Invalid string at constant pool item #" + i + ": " + ex.getMessage()); + } + cpItems[i] = s; + } + return s; + } + + private static boolean isRef(byte b) { + switch (b) { + case CONSTANT_MethodRef: + case CONSTANT_FieldRef: + case CONSTANT_InterfaceMethodRef: + return true; + default: + return false; + } + } + + /** + * @return the name of the class part of the FieldRef, MethodRef, or + * InterfaceMethodRef at constant pool item i + */ + public String getCPRefClass(int i) throws InvalidClassFileException { + if (i < 1 || i >= cpItems.length) { + throw new IllegalArgumentException("Constant pool item #" + i + " out of range"); + } + int offset = cpOffsets[i]; + if (offset == 0 || !isRef(getByte(offset))) { + throw new IllegalArgumentException("Constant pool item #" + i + " is not a Ref"); + } + try { + return getCPClass(getUShort(offset + 1)); + } catch (IllegalArgumentException ex) { + throw new InvalidClassFileException(offset, "Invalid Ref class at constant pool item #" + i + ": " + ex.getMessage()); + } + } + + /** + * @return the name part of the FieldRef, MethodRef, or InterfaceMethodRef at + * constant pool item i + */ + public String getCPRefName(int i) throws InvalidClassFileException { + if (i < 1 || i >= cpItems.length) { + throw new IllegalArgumentException("Constant pool item #" + i + " out of range"); + } + int offset = cpOffsets[i]; + if (offset == 0 || !isRef(getByte(offset))) { + throw new IllegalArgumentException("Constant pool item #" + i + " is not a Ref"); + } + try { + return getCPNATName(getUShort(offset + 3)); + } catch (IllegalArgumentException ex) { + throw new InvalidClassFileException(offset, "Invalid Ref NameAndType at constant pool item #" + i + ": " + ex.getMessage()); + } + } + + /** + * @return the type part of the FieldRef, MethodRef, or InterfaceMethodRef at + * constant pool item i, in JVM format (e.g., I, Z, or + * Ljava/lang/Object;) + */ + public String getCPRefType(int i) throws InvalidClassFileException { + if (i < 1 || i >= cpItems.length) { + throw new IllegalArgumentException("Constant pool item #" + i + " out of range"); + } + int offset = cpOffsets[i]; + if (offset == 0 || !isRef(getByte(offset))) { + throw new IllegalArgumentException("Constant pool item #" + i + " is not a Ref"); + } + try { + return getCPNATType(getUShort(offset + 3)); + } catch (IllegalArgumentException ex) { + throw new InvalidClassFileException(offset, "Invalid Ref NameAndType at constant pool item #" + i + ": " + ex.getMessage()); + } + } + + /** + * @return the name part of the NameAndType at constant pool item i + */ + public String getCPNATName(int i) throws InvalidClassFileException { + if (i < 1 || i >= cpItems.length) { + throw new IllegalArgumentException("Constant pool item #" + i + " out of range"); + } + int offset = cpOffsets[i]; + if (offset == 0 || getByte(offset) != CONSTANT_NameAndType) { + throw new IllegalArgumentException("Constant pool item #" + i + " is not a NameAndType"); + } + try { + return getCPUtf8(getUShort(offset + 1)); + } catch (IllegalArgumentException ex) { + throw new InvalidClassFileException(offset, "Invalid NameAndType name at constant pool item #" + i + ": " + ex.getMessage()); + } + } + + /** + * @return the type part of the NameAndType at constant pool item i, in JVM + * format (e.g., I, Z, or Ljava/lang/Object;) + */ + public String getCPNATType(int i) throws InvalidClassFileException { + if (i < 1 || i >= cpItems.length) { + throw new IllegalArgumentException("Constant pool item #" + i + " out of range"); + } + int offset = cpOffsets[i]; + if (offset == 0 || getByte(offset) != CONSTANT_NameAndType) { + throw new IllegalArgumentException("Constant pool item #" + i + " is not a NameAndType"); + } + try { + return getCPUtf8(getUShort(offset + 3)); + } catch (IllegalArgumentException ex) { + throw new InvalidClassFileException(offset, "Invalid NameAndType type at constant pool item #" + i + ": " + ex.getMessage()); + } + } + + /** + * @return the value of the Integer at constant pool item i + */ + public int getCPInt(int i) throws InvalidClassFileException { + if (i < 1 || i >= cpItems.length) { + throw new IllegalArgumentException("Constant pool item #" + i + " out of range"); + } + int offset = cpOffsets[i]; + if (offset == 0 || getByte(offset) != CONSTANT_Integer) { + throw new IllegalArgumentException("Constant pool item #" + i + " is not an Integer"); + } + return getInt(offset + 1); + } + + /** + * @return the value of the Float at constant pool item i + */ + public float getCPFloat(int i) throws InvalidClassFileException { + if (i < 1 || i >= cpItems.length) { + throw new IllegalArgumentException("Constant pool item #" + i + " out of range"); + } + int offset = cpOffsets[i]; + if (offset == 0 || getByte(offset) != CONSTANT_Float) { + throw new IllegalArgumentException("Constant pool item #" + i + " is not a Float"); + } + return getFloat(offset + 1); + } + + /** + * @return the value of the Long at constant pool item i + */ + public long getCPLong(int i) throws InvalidClassFileException { + if (i < 1 || i >= cpItems.length) { + throw new IllegalArgumentException("Constant pool item #" + i + " out of range"); + } + int offset = cpOffsets[i]; + if (offset == 0 || getByte(offset) != CONSTANT_Long) { + throw new IllegalArgumentException("Constant pool item #" + i + " is not a Long"); + } + return getLong(offset + 1); + } + + /** + * @return the value of the Double at constant pool item i + */ + public double getCPDouble(int i) throws InvalidClassFileException { + if (i < 1 || i >= cpItems.length) { + throw new IllegalArgumentException("Constant pool item #" + i + " out of range"); + } + int offset = cpOffsets[i]; + if (offset == 0 || getByte(offset) != CONSTANT_Double) { + throw new IllegalArgumentException("Constant pool item #" + i + " is not a Double"); + } + return getDouble(offset + 1); + } + + private InvalidClassFileException invalidUtf8(int item, int offset) { + return new InvalidClassFileException(offset, "Constant pool item #" + item + " starting at " + cpOffsets[item] + + ", is an invalid Java Utf8 string (byte is " + getByte(offset) + ")"); + } + + /** + * @return the value of the Utf8 string at constant pool item i + */ + public String getCPUtf8(int i) throws InvalidClassFileException { + if (i < 1 || i >= cpItems.length) { + throw new IllegalArgumentException("Constant pool item #" + i + " out of range"); + } + int offset = cpOffsets[i]; + if (offset == 0 || getByte(offset) != CONSTANT_Utf8) { + throw new IllegalArgumentException("Constant pool item #" + i + " is not a Utf8"); + } + String s = cpItems[i]; + if (s == null) { + int count = getUShort(offset + 1); + int end = count + offset + 3; + StringBuffer buf = new StringBuffer(count); + offset += 3; + while (offset < end) { + byte x = getByte(offset); + if ((x & 0x80) == 0) { + if (x == 0) { + throw invalidUtf8(i, offset); + } + buf.append((char) x); + offset++; + } else if ((x & 0xE0) == 0xC0) { + if (offset + 1 >= end) { + throw invalidUtf8(i, offset); + } + byte y = getByte(offset + 1); + if ((y & 0xC0) != 0x80) { + throw invalidUtf8(i, offset); + } + buf.append((char) (((x & 0x1F) << 6) + (y & 0x3F))); + offset += 2; + } else if ((x & 0xF0) == 0xE0) { + if (offset + 2 >= end) { + throw invalidUtf8(i, offset); + } + byte y = getByte(offset + 1); + byte z = getByte(offset + 2); + if ((y & 0xC0) != 0x80 || (z & 0xC0) != 0x80) { + throw invalidUtf8(i, offset); + } + buf.append((char) (((x & 0x0F) << 12) + ((y & 0x3F) << 6) + (z & 0x3F))); + offset += 3; + } else { + throw invalidUtf8(i, offset); + } + } + s = buf.toString().intern(); + cpItems[i] = s; + } + return s; + } + + private void parseConstantPool(int offset, int itemCount) throws InvalidClassFileException { + cpOffsets = new int[itemCount + 1]; + cpItems = new String[itemCount]; + for (int i = 1; i < itemCount; i++) { + cpOffsets[i] = offset; + byte tag = getByte(offset); + int itemLen; + switch (tag) { + case CONSTANT_String: + case CONSTANT_Class: + itemLen = 2; + break; + case CONSTANT_NameAndType: + case CONSTANT_MethodRef: + case CONSTANT_FieldRef: + case CONSTANT_InterfaceMethodRef: + case CONSTANT_Integer: + case CONSTANT_Float: + itemLen = 4; + break; + case CONSTANT_Long: + case CONSTANT_Double: + itemLen = 8; + i++; // ick + break; + case CONSTANT_Utf8: + itemLen = 2 + getUShort(offset + 1); + break; + default: + throw new InvalidClassFileException(offset, "unknown constant pool entry type" + tag); + } + checkLength(offset, itemLen); + offset += itemLen + 1; + } + cpOffsets[itemCount] = offset; + } + + private byte getByte(int i) { + return bytes[i]; + } + + private int getUShort(int i) { + return ((bytes[i] & 0xFF) << 8) + (bytes[i + 1] & 0xFF); + } + +// private short getShort(int i) { +// return (short) ((bytes[i] << 8) + (bytes[i + 1] & 0xFF)); +// } + + private int getInt(int i) { + return (bytes[i] << 24) + ((bytes[i + 1] & 0xFF) << 16) + ((bytes[i + 2] & 0xFF) << 8) + (bytes[i + 3] & 0xFF); + } + + private long getLong(int i) { + return ((long) getInt(i) << 32) + ((long) getInt(i + 4) & 0xFFFFFFFFL); + } + + private float getFloat(int i) { + return Float.intBitsToFloat(getInt(i)); + } + + private double getDouble(int i) { + return Double.longBitsToDouble(getLong(i)); + } +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeCT/ConstantValueReader.java b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeCT/ConstantValueReader.java new file mode 100644 index 000000000..d565a4f08 --- /dev/null +++ b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeCT/ConstantValueReader.java @@ -0,0 +1,32 @@ +/******************************************************************************* + * 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.shrikeCT; + +/** + * This class reads ConstantValue attributes. + */ +public final class ConstantValueReader extends ClassReaderAttribute { + /** + * Build a reader for the attribute 'iter'. + */ + public ConstantValueReader(ClassReader.AttrIterator iter) throws InvalidClassFileException { + super(iter, "ConstantValue"); + + checkSizeEquals(attr + 6, 2); + } + + /** + * @return the index of the constant pool item holding the value + */ + public int getValueCPIndex() { + return cr.getUShort(attr + 6); + } +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeCT/ConstantValueWriter.java b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeCT/ConstantValueWriter.java new file mode 100644 index 000000000..aa518267e --- /dev/null +++ b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeCT/ConstantValueWriter.java @@ -0,0 +1,136 @@ +/******************************************************************************* + * 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.shrikeCT; + +/** + * This class builds serializable ConstantValue attributes. These attributes are + * associated with final fields. + * + * After constructing a ConstantValueWriter, you must call setValueCPIndex. + */ +public final class ConstantValueWriter extends ClassWriter.Element { + private int attrID; + private int index = -1; + private ClassWriter w; + + /** + * Build an empty writer. + */ + public ConstantValueWriter(ClassWriter w) { + this.w = w; + attrID = w.addCPUtf8("ConstantValue"); + } + + /** + * Build an writer for a 'long' constant value. + */ + public ConstantValueWriter(ClassWriter w, long v) { + this(w); + setLong(v); + } + + /** + * Build an writer for an 'int' constant value. + */ + public ConstantValueWriter(ClassWriter w, int v) { + this(w); + setInt(v); + } + + /** + * Build an writer for a 'float' constant value. + */ + public ConstantValueWriter(ClassWriter w, float v) { + this(w); + setFloat(v); + } + + /** + * Build an writer for a 'double' constant value. + */ + public ConstantValueWriter(ClassWriter w, double v) { + this(w); + setDouble(v); + } + + /** + * Build an writer for a 'String' constant value. + */ + public ConstantValueWriter(ClassWriter w, String v) { + this(w); + setString(v); + } + + private void verify() { + if (index < 0) { + throw new IllegalArgumentException("The value's constant pool index is not set"); + } + } + + public int getSize() { + verify(); + return 8; + } + + public int copyInto(byte[] buf, int offset) { + verify(); + ClassWriter.setUShort(buf, offset, attrID); + ClassWriter.setInt(buf, offset + 2, 2); + ClassWriter.setUShort(buf, offset + 6, index); + return offset + 8; + } + + /** + * Set the constant value to a long. + */ + public void setLong(long value) { + this.index = w.addCPLong(value); + } + + /** + * Set the constant value to a double. + */ + public void setDouble(double value) { + this.index = w.addCPDouble(value); + } + + /** + * Set the constant value to an int. + */ + public void setInt(int value) { + this.index = w.addCPInt(value); + } + + /** + * Set the constant value to a float. + */ + public void setFloat(float value) { + this.index = w.addCPFloat(value); + } + + /** + * Set the constant value to a String. + */ + public void setString(String value) { + this.index = w.addCPString(value); + } + + /** + * Set the index of the constant pool item holding the constant value. + */ + public void setValueCPIndex(int index) { + if (index < 1 || index > 0xFFFF) { + throw new IllegalArgumentException("Invalid CP index: " + index); + } + + this.index = index; + } +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeCT/ExceptionsReader.java b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeCT/ExceptionsReader.java new file mode 100644 index 000000000..850c91fda --- /dev/null +++ b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeCT/ExceptionsReader.java @@ -0,0 +1,52 @@ +/******************************************************************************* + * 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.shrikeCT; + +/** + * This class reads Exceptions attributes. + */ +public final class ExceptionsReader extends ClassReaderAttribute { + /** + * Build a reader for the attribute 'iter'. + */ + public ExceptionsReader(ClassReader.AttrIterator iter) throws InvalidClassFileException { + super(iter, "Exceptions"); + + checkSize(attr, 8); + int count = cr.getUShort(attr + 6); + checkSizeEquals(attr + 8, 2 * count); + } + + /** + * @return the indices of the constant pool items for the exceptions + */ + public int[] getRawTable() { + int count = cr.getUShort(attr + 6); + int[] r = new int[count]; + for (int i = 0; i < r.length; i++) { + r[i] = cr.getUShort(attr + 8 + i * 2); + } + return r; + } + + /** + * @return the classes of exceptions that can be thrown by the method + */ + public String[] getClasses() throws InvalidClassFileException { + int count = cr.getUShort(attr + 6); + String[] r = new String[count]; + ConstantPoolParser cp = cr.getCP(); + for (int i = 0; i < r.length; i++) { + r[i] = cp.getCPClass(cr.getUShort(attr + 8 + i * 2)); + } + return r; + } +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeCT/ExceptionsWriter.java b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeCT/ExceptionsWriter.java new file mode 100644 index 000000000..3a01032e7 --- /dev/null +++ b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeCT/ExceptionsWriter.java @@ -0,0 +1,60 @@ +/******************************************************************************* + * 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.shrikeCT; + +/** + * This class builds serializable Exceptions attributes. + */ +public final class ExceptionsWriter extends ClassWriter.Element { + private int attrID; + private int[] table; + + /** + * Build an empty writer. + */ + public ExceptionsWriter(ClassWriter w) { + attrID = w.addCPUtf8("Exceptions"); + } + + public int getSize() { + return table == null ? 8 : 8 + table.length * 2; + } + + public int copyInto(byte[] buf, int offset) { + ClassWriter.setUShort(buf, offset, attrID); + ClassWriter.setInt(buf, offset + 2, getSize() - 6); + ClassWriter.setUShort(buf, offset + 6, table == null ? 0 : table.length); + offset += 8; + if (table != null) { + for (int i = 0; i < table.length; i++) { + ClassWriter.setUShort(buf, offset, table[i]); + offset += 2; + } + } + return offset; + } + + /** + * Set the list of exceptions that can be thrown. + * + * @param exceptions + * an array of indices to constant pool Class entries + */ + public void setRawTable(int[] exceptions) { + for (int i = 0; i < exceptions.length; i++) { + if (exceptions[i] < 1 || exceptions[i] > 0xFFFF) { + throw new IllegalArgumentException("Invalid CP index: " + exceptions[i]); + } + } + + this.table = exceptions; + } +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeCT/InnerClassesReader.java b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeCT/InnerClassesReader.java new file mode 100644 index 000000000..24bbbdf95 --- /dev/null +++ b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeCT/InnerClassesReader.java @@ -0,0 +1,39 @@ +/******************************************************************************* + * 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.shrikeCT; + +/** + * This class reads InnerClasses attributes. + */ +public final class InnerClassesReader extends ClassReaderAttribute { + /** + * Build a reader for the attribute 'iter'. + */ + public InnerClassesReader(ClassReader.AttrIterator iter) throws InvalidClassFileException { + super(iter, "InnerClasses"); + + checkSize(attr, 8); + int count = cr.getUShort(attr + 6); + checkSizeEquals(attr + 8, 8 * count); + } + + /** + * @return the raw values that make up this attribute + */ + public int[] getRawTable() { + int count = cr.getUShort(attr + 6); + int[] r = new int[count * 4]; + for (int i = 0; i < r.length; i++) { + r[i] = cr.getUShort(attr + 8 + i * 2); + } + return r; + } +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeCT/InnerClassesWriter.java b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeCT/InnerClassesWriter.java new file mode 100644 index 000000000..1d19cbc4c --- /dev/null +++ b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeCT/InnerClassesWriter.java @@ -0,0 +1,66 @@ +/******************************************************************************* + * 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.shrikeCT; + +/** + * This class builds serializable InnerClasses attributes. + */ +public final class InnerClassesWriter extends ClassWriter.Element { + private int attrID; + private int[] table; + + /** + * Build an empty writer. + */ + public InnerClassesWriter(ClassWriter w) { + attrID = w.addCPUtf8("InnerClasses"); + } + + public int getSize() { + return table == null ? 8 : 8 + table.length * 2; + } + + public int copyInto(byte[] buf, int offset) { + ClassWriter.setUShort(buf, offset, attrID); + ClassWriter.setInt(buf, offset + 2, getSize() - 6); + ClassWriter.setUShort(buf, offset + 6, table == null ? 0 : table.length); + offset += 8; + if (table != null) { + for (int i = 0; i < table.length; i++) { + ClassWriter.setUShort(buf, offset, table[i]); + offset += 2; + } + } + return offset; + } + + /** + * Set the raw values that make up this attribute + */ + public void setRawTable(int[] classes) { + if (classes.length % 4 != 0) { + throw new IllegalArgumentException("Invalid raw table length: " + classes.length); + } + for (int i = 0; i < classes.length; i += 4) { + if (classes[i] < 1 || classes[i] > 0xFFFF) { + throw new IllegalArgumentException("Invalid CP index: " + classes[i]); + } + if (classes[i + 1] < 0 || classes[i + 1] > 0xFFFF) { + throw new IllegalArgumentException("Invalid CP index: " + classes[i]); + } + if (classes[i + 2] < 0 || classes[i + 2] > 0xFFFF) { + throw new IllegalArgumentException("Invalid CP index: " + classes[i]); + } + } + + this.table = classes; + } +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeCT/InvalidClassFileException.java b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeCT/InvalidClassFileException.java new file mode 100644 index 000000000..65887736f --- /dev/null +++ b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeCT/InvalidClassFileException.java @@ -0,0 +1,41 @@ +/******************************************************************************* + * 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.shrikeCT; + +/** + * This exception is thrown when we detect that the incoming class file data was + * not a valid class file. + */ +public class InvalidClassFileException extends Exception { + + private static final long serialVersionUID = -6224203694783674259L; + private int offset; + + /** + * The incoming class file is invalid. + * + * @param offset + * the offset within the data where the invalidity was detected + * @param s + * the reason the data is invalid + */ + public InvalidClassFileException(int offset, String s) { + super("Class file invalid at " + offset + ": " + s); + this.offset = offset; + } + + /** + * @return the offset within the data where the problem was detected + */ + public int getOffset() { + return offset; + } +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeCT/LineNumberTableReader.java b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeCT/LineNumberTableReader.java new file mode 100644 index 000000000..f7e50e0ed --- /dev/null +++ b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeCT/LineNumberTableReader.java @@ -0,0 +1,104 @@ +/******************************************************************************* + * 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.shrikeCT; + +/** + * This class reads LineNumberTable attributes. + * + * Instead of constructing a LineNumberTableReader directly, consider just + * calling LineNumberTableReader.makeBytecodeToSourceMap for convenient access + * to aggregate line number data from all the LineNumberTable attributes for a + * given Code. + */ +public final class LineNumberTableReader extends ClassReaderAttribute { + /** + * Build a reader for a LineNumberTable attribute. + */ + public LineNumberTableReader(ClassReader.AttrIterator iter) throws InvalidClassFileException { + super(iter, "LineNumberTable"); + + int offset = attr + 6; + checkSize(offset, 2); + int count = cr.getUShort(offset); + offset += 2; + checkSize(offset, count * 4); + } + + /** + * @return the raw line number table data, a flattened sequence of (startPC, + * lineNumber) pairs + */ + public int[] getRawTable() { + int count = cr.getUShort(attr + 6); + int[] r = new int[count * 2]; + int offset = attr + 8; + for (int i = 0; i < r.length; i++) { + r[i] = cr.getUShort(offset); + offset += 2; + } + return r; + } + + /** + * Construct a "bytecode to source" map for the given code. This method + * aggregates all the LineNumberTable attributes for the code into one handy + * data structure. + * + * @return an array mapping each byte of the bytecode bytes to the line number + * that that byte belongs to, or null if there is no line number data + * in the Code + */ + public static int[] makeBytecodeToSourceMap(CodeReader code) throws InvalidClassFileException { + int[] r = null; + ClassReader cr = code.getClassReader(); + + ClassReader.AttrIterator iter = new ClassReader.AttrIterator(); + code.initAttributeIterator(iter); + for (; iter.isValid(); iter.advance()) { + if (iter.getName().equals("LineNumberTable")) { + if (r == null) { + r = new int[code.getBytecodeLength()]; + } + + // check length + new LineNumberTableReader(iter); + int attr = iter.getRawOffset(); + int count = cr.getUShort(attr + 6); + int offset = attr + 8; + for (int j = 0; j < count; j++) { + int startPC = cr.getUShort(offset); + int lineNum = cr.getUShort(offset + 2); + offset += 4; + + if (startPC < 0 || startPC >= r.length) { + throw new InvalidClassFileException(offset, "Invalid bytecode offset " + startPC + " in LineNumberTable"); + } + r[startPC] = lineNum; + } + } + } + + if (r != null) { + // fill in gaps in the old line number map + int last = 0; + for (int i = 0; i < r.length; i++) { + int cur = r[i]; + if (cur == 0) { + r[i] = last; + } else { + last = cur; + } + } + } + + return r; + } +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeCT/LineNumberTableWriter.java b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeCT/LineNumberTableWriter.java new file mode 100644 index 000000000..d17523b65 --- /dev/null +++ b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeCT/LineNumberTableWriter.java @@ -0,0 +1,104 @@ +/******************************************************************************* + * 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.shrikeCT; + +/** + * This class helps emit LineNumberTable attributes. + */ +public final class LineNumberTableWriter extends ClassWriter.Element { + private int attrID; + private int[] rawTable = emptyTable; + + private static final int[] emptyTable = new int[0]; + + /** + * Build an empty LineNumberTable. + */ + public LineNumberTableWriter(ClassWriter w) { + attrID = w.addCPUtf8("LineNumberTable"); + } + + /** + * Set the raw table entries. Consider calling + * LineNumberTableWriter.makeRawTable to build the raw entries. + * + * @param table + * a flattened sequence of (startPC, lineNumber) pairs + */ + public void setRawTable(int[] table) { + if (table == null) { + table = emptyTable; + } + + if (table.length % 2 != 0) { + throw new IllegalArgumentException("Line number table has bad length: " + table.length); + } + if (table.length / 2 > 0xFFFF) { + throw new IllegalArgumentException("Too many line number table entries: " + table.length / 2); + } + for (int i = 0; i < table.length; i++) { + int v = table[i]; + if (v < 0 || v > 0xFFFF) { + throw new IllegalArgumentException("Bad line number table entry at " + i + ": " + v); + } + } + + rawTable = table; + } + + public int getSize() { + return 8 + rawTable.length * 2; + } + + public int copyInto(byte[] buf, int offset) { + ClassWriter.setUShort(buf, offset, attrID); + ClassWriter.setInt(buf, offset + 2, 2 + rawTable.length * 2); + ClassWriter.setUShort(buf, offset + 6, rawTable.length / 2); + offset += 8; + for (int i = 0; i < rawTable.length; i++) { + ClassWriter.setUShort(buf, offset, rawTable[i]); + offset += 2; + } + + return offset; + } + + /** + * @param newLineMap + * an array indexed by bytecode offset, mapping each bytecode offset + * to its line number (or 0 if there is no line or it's not known) + * @return the line numbers in "raw" format, a flattened sequence of (startPC, + * lineNumber) pairs + */ + public static int[] makeRawTable(int[] newLineMap) { + int rawCount = 0; + int last = -1; + for (int i = 0; i < newLineMap.length; i++) { + int next = newLineMap[i]; + if (next != last) { + rawCount++; + } + } + int[] rawTable = new int[rawCount * 2]; + last = -1; + int index = 0; + for (int i = 0; i < newLineMap.length; i++) { + int next = newLineMap[i]; + if (next != last) { + rawTable[index] = i; + rawTable[index + 1] = next; + index += 2; + } + } + return rawTable; + } +} + diff --git a/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeCT/LocalVariableTableReader.java b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeCT/LocalVariableTableReader.java new file mode 100644 index 000000000..8dc8512b6 --- /dev/null +++ b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeCT/LocalVariableTableReader.java @@ -0,0 +1,120 @@ +/******************************************************************************* + * 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.shrikeCT; + +/** + * This class reads LocalVariableTable attributes. + * + * Instead of constructing a LocalVariableTable directly, consider just calling + * LocalVariableTable.makeVarMap for convenient access to aggregate local + * variable data from all the LocalVariableTable attributes for a given Code. + */ +public final class LocalVariableTableReader extends ClassReaderAttribute { + public LocalVariableTableReader(ClassReader.AttrIterator iter) throws InvalidClassFileException { + super(iter, "LocalVariableTable"); + + int offset = attr + 6; + checkSize(offset, 2); + int count = cr.getUShort(offset); + offset += 2; + checkSize(offset, count * 10); + } + + /** + * @return the raw line number table data, a flattened sequence of (startPC, + * PClength, nameIndex, typeIndex, var) tuples + */ + public int[] getRawTable() { + int count = cr.getUShort(attr + 6); + int[] r = new int[count * 5]; + int offset = attr + 8; + for (int i = 0; i < r.length; i++) { + r[i] = cr.getUShort(offset); + offset += 2; + } + return r; + } + + private static int[] makeVarVector(int[] curVector, int varIndex, int nameIndex, int typeIndex) { + int[] newVector; + if (curVector == null) { + newVector = new int[(varIndex + 1) * 2]; + } else { + newVector = new int[Math.max(curVector.length, (varIndex + 1) * 2)]; + System.arraycopy(curVector, 0, newVector, 0, curVector.length); + } + newVector[varIndex * 2] = nameIndex; + newVector[varIndex * 2 + 1] = typeIndex; + return newVector; + } + + /** + * @return an array mapping bytecode offsets to arrays representing the local + * variable maps for each offset; a local variable map is represented + * as an array of localVars*2 elements, containing a pair (nameIndex, + * typeIndex) for each local variable; a pair (0,0) indicates there is + * no information for that local variable at that offset + */ + public static int[][] makeVarMap(CodeReader code) throws InvalidClassFileException { + int[][] r = null; + ClassReader cr = code.getClassReader(); + + ClassReader.AttrIterator iter = new ClassReader.AttrIterator(); + code.initAttributeIterator(iter); + for (; iter.isValid(); iter.advance()) { + if (iter.getName().equals("LocalVariableTable")) { + if (r == null) { + r = new int[code.getBytecodeLength()][]; + } + + // check length + new LocalVariableTableReader(iter); + int attr = iter.getRawOffset(); + int count = cr.getUShort(attr + 6); + int offset = attr + 8; + for (int j = 0; j < count; j++) { + int startPC = cr.getUShort(offset); + int length = cr.getUShort(offset + 2); + int nameIndex = cr.getUShort(offset + 4); + int typeIndex = cr.getUShort(offset + 6); + int varIndex = cr.getUShort(offset + 8); + offset += 10; + + if (varIndex < 0) { + throw new InvalidClassFileException(offset, "Invalid variable index " + varIndex + " in LocalVariableTable"); + } else if (startPC < 0) { + throw new InvalidClassFileException(offset, "Invalid startPC " + startPC + " in LocalVariableTable"); + } else if (startPC + length > r.length) { + throw new InvalidClassFileException(offset, "Invalid startPC+length " + (startPC + length) + " > " + r.length + + " in LocalVariableTable"); + } + + int rangeStart = startPC; + while (rangeStart < startPC + length) { + int rangeLength = 1; + while (rangeStart + rangeLength < startPC + length && r[rangeStart + rangeLength] == r[rangeStart]) { + rangeLength++; + } + + int[] newVector = makeVarVector(r[rangeStart], varIndex, nameIndex, typeIndex); + for (int k = rangeStart; k < rangeStart + rangeLength; k++) { + r[k] = newVector; + } + + rangeStart += rangeLength; + } + } + } + } + + return r; + } +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeCT/LocalVariableTableWriter.java b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeCT/LocalVariableTableWriter.java new file mode 100644 index 000000000..624b2f8b0 --- /dev/null +++ b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeCT/LocalVariableTableWriter.java @@ -0,0 +1,145 @@ +/******************************************************************************* + * 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.shrikeCT; + +import java.util.Arrays; + +/** + * This class helps emit LocalVariableTable attributes. + */ +public final class LocalVariableTableWriter extends ClassWriter.Element { + private int attrID; + private int[] rawTable = emptyTable; + + private static final int[] emptyTable = new int[0]; + + /** + * Create a blank LocalVariableTable. + */ + public LocalVariableTableWriter(ClassWriter w) { + attrID = w.addCPUtf8("LocalVariableTable"); + } + + /** + * Set the raw local variable table values. Consider using + * LocalVariableTableWriter.makeRawTable to build the raw values. + * + * @param table + * the raw values, a flattened sequence of (startPC, length, + * nameIndex, typeIndex, var) tuples + */ + public void setRawTable(int[] table) { + if (table == null) { + table = emptyTable; + } + + if (table.length % 5 != 0) { + throw new IllegalArgumentException("Local variable table has bad length: " + table.length); + } + if (table.length / 5 > 0xFFFF) { + throw new IllegalArgumentException("Too many local variable table entries: " + table.length / 5); + } + for (int i = 0; i < table.length; i++) { + int v = table[i]; + if (v < 0 || v > 0xFFFF) { + throw new IllegalArgumentException("Bad local variable table entry at " + i + ": " + v); + } + } + + rawTable = table; + } + + public int getSize() { + return 8 + rawTable.length * 2; + } + + public int copyInto(byte[] buf, int offset) { + ClassWriter.setUShort(buf, offset, attrID); + ClassWriter.setInt(buf, offset + 2, 2 + rawTable.length * 2); + ClassWriter.setUShort(buf, offset + 6, rawTable.length / 5); + offset += 8; + for (int i = 0; i < rawTable.length; i++) { + ClassWriter.setUShort(buf, offset, rawTable[i]); + offset += 2; + } + + return offset; + } + + /** + * Build a raw local variable table from a formatted variable map. + * + * @param varMap + * an array mapping bytecode offsets to a variable map for each + * offset; a variable map is a array of 2*localVars elements, + * containing a (nameIndex, typeIndex) for each local variable; the + * pair (0,0) indicates that there is no information about that local + * variable at that offset + */ + public static int[] makeRawTable(int[][] varMap) { + int varCount = 0; + for (int i = 0; i < varMap.length; i++) { + if (varMap[i] != null) { + varCount = Math.max(varCount, varMap[i].length); + } + } + varCount /= 2; + + int[] entries = new int[20]; + int[] varEnd = new int[varCount]; + Arrays.fill(varEnd, -1); + int[] lastVector = null; + int entryCount = 0; + for (int i = 0; i < varMap.length; i++) { + if (varMap[i] != lastVector) { + lastVector = varMap[i]; + + if (lastVector != null) { + for (int k = 0; k < lastVector.length / 2; k++) { + if (lastVector[k * 2] > 0 && i >= varEnd[k]) { + int entryOffset = entryCount * 5; + entryCount++; + if (entryCount * 5 > entries.length) { + int[] newEntries = new int[entries.length * 2]; + System.arraycopy(entries, 0, newEntries, 0, entries.length); + entries = newEntries; + } + int nameIndex = lastVector[k * 2]; + int typeIndex = lastVector[k * 2 + 1]; + int end = i + 1; + while (end < varMap.length) { + if (varMap[end] == null || k * 2 >= varMap[end].length || varMap[end][k * 2] != nameIndex + || varMap[end][k * 2 + 1] != typeIndex) { + break; + } + end++; + } + varEnd[k] = end; + entries[entryOffset] = i; + entries[entryOffset + 1] = end - i; + entries[entryOffset + 2] = nameIndex; + entries[entryOffset + 3] = typeIndex; + entries[entryOffset + 4] = k; + } + } + } + } + } + + if (entryCount == 0) { + return null; + } else { + int[] r = new int[entryCount * 5]; + System.arraycopy(entries, 0, r, 0, r.length); + return r; + } + } +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeCT/SourceDebugExtensionReader.java b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeCT/SourceDebugExtensionReader.java new file mode 100644 index 000000000..8a33d4dc7 --- /dev/null +++ b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeCT/SourceDebugExtensionReader.java @@ -0,0 +1,25 @@ +/******************************************************************************* + * 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.shrikeCT; + +public class SourceDebugExtensionReader extends ClassReaderAttribute { + public SourceDebugExtensionReader(ClassReader.AttrIterator iter) throws InvalidClassFileException { + super(iter, "SourceDebugExtension"); + + checkSize(attr, 6); + + + } + + +} + + diff --git a/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeCT/SourceDebugExtensionWriter.java b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeCT/SourceDebugExtensionWriter.java new file mode 100644 index 000000000..4412c0583 --- /dev/null +++ b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeCT/SourceDebugExtensionWriter.java @@ -0,0 +1,59 @@ +/******************************************************************************* + * 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.shrikeCT; + +import java.io.UnsupportedEncodingException; + +import com.ibm.wala.shrikeCT.ClassWriter; + +public class SourceDebugExtensionWriter extends ClassWriter.Element { + private int attrID; + private byte[] table; + + public SourceDebugExtensionWriter(ClassWriter w){ + attrID = w.addCPUtf8("SourceDebugExtension"); + } + + public int getSize() { + return table == null ? 6 : 6 + table.length; + } + + public int copyInto(byte[] buf, int offset) { + ClassWriter.setUShort(buf, offset, attrID); + ClassWriter.setInt(buf, offset + 2, getSize() - 6); + offset += 6; + if (table != null) { + for (int i = 0; i < table.length; i++) { + ClassWriter.setUByte(buf, offset, table[i]); + offset++; + } + } + return offset; + } + + public void setRawTable(byte[] sourceDebug){ + for(int i = 0; i < sourceDebug.length ; i++){ + if (sourceDebug[i] < 1 || sourceDebug[i] > 0xFFFF) { + throw new IllegalArgumentException("Invalid CP index: " + sourceDebug[i]); + } + } + this.table = sourceDebug; + } + + public void setDebugInfo(String sourceDebug){ + try { + byte[] bytes = sourceDebug.getBytes("UTF8"); + setRawTable(bytes); + } catch (UnsupportedEncodingException e){ + System.err.println(e); + } + } +} diff --git a/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeCT/SourceFileReader.java b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeCT/SourceFileReader.java new file mode 100644 index 000000000..c89c56173 --- /dev/null +++ b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeCT/SourceFileReader.java @@ -0,0 +1,32 @@ +/******************************************************************************* + * 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.shrikeCT; + +/** + * This class reads SourceFile attributes. + */ +public final class SourceFileReader extends ClassReaderAttribute { + /** + * Build a reader for the attribute 'iter'. + */ + public SourceFileReader(ClassReader.AttrIterator iter) throws InvalidClassFileException { + super(iter, "SourceFile"); + + checkSizeEquals(attr + 6, 2); + } + + /** + * @return the index of the constant pool item holding the value + */ + public int getSourceFileCPIndex() { + return cr.getUShort(attr + 6); + } +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeCT/SourceFileWriter.java b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeCT/SourceFileWriter.java new file mode 100644 index 000000000..3237b1dbd --- /dev/null +++ b/com.ibm.wala.shrike/com.ibm.wala.shrike/src/com/ibm/wala/shrikeCT/SourceFileWriter.java @@ -0,0 +1,58 @@ +/******************************************************************************* + * 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.shrikeCT; + +/** + * This class builds serializable SourceFile attributes. + * + * After constructing a SourceFileWriter, you must call setSourceFileCPIndex. + */ +public final class SourceFileWriter extends ClassWriter.Element { + private int attrID; + private int index = -1; + + /** + * Build an empty writer. + */ + public SourceFileWriter(ClassWriter w) { + attrID = w.addCPUtf8("SourceFile"); + } + + private void verify() { + if (index < 0) { + throw new IllegalArgumentException("The value's constant pool index is not set"); + } + } + + public int getSize() { + verify(); + return 8; + } + + public int copyInto(byte[] buf, int offset) { + verify(); + ClassWriter.setUShort(buf, offset, attrID); + ClassWriter.setInt(buf, offset + 2, 2); + ClassWriter.setUShort(buf, offset + 6, index); + return offset + 8; + } + + /** + * Set the index of the constant pool item holding the source file name. + */ + public void setSourceFileCPIndex(int index) { + if (index < 1 || index > 0xFFFF) { + throw new IllegalArgumentException("Invalid CP index: " + index); + } + + this.index = index; + } +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/exportPlugin.xml b/com.ibm.wala.shrike/exportPlugin.xml new file mode 100644 index 000000000..234124335 --- /dev/null +++ b/com.ibm.wala.shrike/exportPlugin.xml @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/com.ibm.wala.shrike/javaCompiler...args b/com.ibm.wala.shrike/javaCompiler...args new file mode 100644 index 000000000..051894b39 --- /dev/null +++ b/com.ibm.wala.shrike/javaCompiler...args @@ -0,0 +1,14 @@ +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.core.runtime_3.2.0.v20060603.jar[~org/eclipse/core/internal/preferences/legacy/*;~org/eclipse/core/internal/runtime/*;+org/eclipse/core/runtime/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.osgi_3.2.0.v20060601.jar[+org/eclipse/osgi/event/*;+org/eclipse/osgi/framework/console/*;+org/eclipse/osgi/framework/eventmgr/*;+org/eclipse/osgi/framework/log/*;+org/eclipse/osgi/service/datalocation/*;+org/eclipse/osgi/service/debug/*;+org/eclipse/osgi/service/environment/*;+org/eclipse/osgi/service/localization/*;+org/eclipse/osgi/service/pluginconversion/*;+org/eclipse/osgi/service/resolver/*;+org/eclipse/osgi/service/runnable/*;+org/eclipse/osgi/service/urlconversion/*;+org/eclipse/osgi/storagemanager/*;+org/eclipse/osgi/util/*;+org/osgi/framework/*;+org/osgi/service/condpermadmin/*;+org/osgi/service/packageadmin/*;+org/osgi/service/permissionadmin/*;+org/osgi/service/startlevel/*;+org/osgi/service/url/*;+org/osgi/util/tracker/*;~org/eclipse/core/runtime/adaptor/*;~org/eclipse/core/runtime/internal/adaptor/*;~org/eclipse/core/runtime/internal/stats/*;~org/eclipse/osgi/baseadaptor/*;~org/eclipse/osgi/baseadaptor/bundlefile/*;~org/eclipse/osgi/baseadaptor/hooks/*;~org/eclipse/osgi/baseadaptor/loader/*;~org/eclipse/osgi/framework/adaptor/*;~org/eclipse/osgi/framework/debug/*;~org/eclipse/osgi/framework/internal/core/*;~org/eclipse/osgi/framework/internal/protocol/*;~org/eclipse/osgi/framework/internal/protocol/bundleentry/*;~org/eclipse/osgi/framework/internal/protocol/bundleresource/*;~org/eclipse/osgi/framework/internal/protocol/reference/*;~org/eclipse/osgi/framework/internal/reliablefile/*;~org/eclipse/osgi/framework/launcher/*;~org/eclipse/osgi/framework/util/*;~org/eclipse/osgi/internal/baseadaptor/*;~org/eclipse/osgi/internal/module/*;~org/eclipse/osgi/internal/profile/*;~org/eclipse/osgi/internal/resolver/*;~org/eclipse/osgi/internal/verifier/*;~org/eclipse/osgi/internal/provisional/verifier/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.equinox.common_3.2.0.v20060603.jar[~org/eclipse/core/internal/runtime/*;~org/eclipse/core/internal/boot/*;+org/eclipse/core/runtime/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.core.jobs_3.2.0.v20060603.jar[~org/eclipse/core/internal/jobs/*;+org/eclipse/core/runtime/jobs/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.core.runtime.compatibility.registry_3.2.0.v20060603/runtime_registry_compatibility.jar[~org/eclipse/core/internal/registry/*;~org/eclipse/core/internal/registry/osgi/*;~org/eclipse/core/internal/registry/spi/*;+org/eclipse/core/runtime/*;+org/eclipse/core/runtime/dynamichelpers/*;+org/eclipse/core/runtime/spi/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.core.runtime.compatibility.registry_3.2.0.v20060603[~org/eclipse/core/internal/registry/*;~org/eclipse/core/internal/registry/osgi/*;~org/eclipse/core/internal/registry/spi/*;+org/eclipse/core/runtime/*;+org/eclipse/core/runtime/dynamichelpers/*;+org/eclipse/core/runtime/spi/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.equinox.registry_3.2.0.v20060601.jar[~org/eclipse/core/internal/registry/*;~org/eclipse/core/internal/registry/osgi/*;~org/eclipse/core/internal/registry/spi/*;+org/eclipse/core/runtime/*;+org/eclipse/core/runtime/dynamichelpers/*;+org/eclipse/core/runtime/spi/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.apache.xerces_2.8.0.v200606131651/resolver.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.apache.xerces_2.8.0.v200606131651/xercesImpl.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.apache.xerces_2.8.0.v200606131651/xml-apis.jar[?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.equinox.preferences_3.2.0.v20060601.jar[~org/eclipse/core/internal/preferences/*;~org/eclipse/core/internal/preferences/exchange/*;+org/eclipse/core/runtime/preferences/*;+org/osgi/service/prefs/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.core.runtime.compatibility.registry_3.2.0.v20060603/@dot[~org/eclipse/core/internal/registry/*;~org/eclipse/core/internal/registry/osgi/*;~org/eclipse/core/internal/registry/spi/*;+org/eclipse/core/runtime/*;+org/eclipse/core/runtime/dynamichelpers/*;+org/eclipse/core/runtime/spi/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.core.contenttype_3.2.0.v20060603.jar[~org/eclipse/core/internal/content/*;+org/eclipse/core/runtime/content/*;?**/*] +#ADAPTER#ACCESS#eclipse/plugins/org.eclipse.core.runtime.compatibility.auth_3.2.0.v20060601.jar[?**/*] diff --git a/com.ibm.wala.shrike/src/com/ibm/wala/shrike/bench/AddBytecodeDebug.java b/com.ibm.wala.shrike/src/com/ibm/wala/shrike/bench/AddBytecodeDebug.java new file mode 100644 index 000000000..4b07b5f97 --- /dev/null +++ b/com.ibm.wala.shrike/src/com/ibm/wala/shrike/bench/AddBytecodeDebug.java @@ -0,0 +1,103 @@ +/******************************************************************************* + * 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.FileWriter; +import java.io.Writer; + +import com.ibm.wala.shrikeBT.DupInstruction; +import com.ibm.wala.shrikeBT.ExceptionHandler; +import com.ibm.wala.shrikeBT.MethodData; +import com.ibm.wala.shrikeBT.MethodEditor; +import com.ibm.wala.shrikeBT.Util; +import com.ibm.wala.shrikeBT.MethodEditor.Output; +import com.ibm.wala.shrikeBT.shrikeCT.ClassInstrumenter; +import com.ibm.wala.shrikeBT.shrikeCT.OfflineInstrumenter; +import com.ibm.wala.shrikeCT.ClassWriter; + +/** + * This is a demo class. + * + * Class files are taken as input arguments (or if there are none, from standard + * input). The methods in those files are instrumented: we insert a + * System.err.println() at ever method call, and a System.err.println() at every + * method entry. + * + * In Unix, I run it like this: java -cp ~/dev/shrike/shrike + * com.ibm.wala.shrikeBT.shrikeCT.tools.Bench test.jar -o output.jar + * + * The instrumented classes are placed in the directory "output" under the + * current directory. Disassembled code is written to the file "report" under + * the current directory. + * + * @author Rob O' Callahan + */ +public class AddBytecodeDebug { + private static OfflineInstrumenter instrumenter; + + public static void main(String[] args) throws Exception { + for (int i = 0; i < 1; i++) { + instrumenter = new OfflineInstrumenter(); + + Writer w = new BufferedWriter(new FileWriter("report", false)); + + args = instrumenter.parseStandardArgs(args); + instrumenter.setPassUnmodifiedClasses(true); + instrumenter.beginTraversal(); + ClassInstrumenter ci; + while ((ci = instrumenter.nextClass()) != null) { + doClass(ci, w); + } + instrumenter.close(); + } + } + + private static void doClass(final ClassInstrumenter ci, Writer w) throws Exception { + final String className = ci.getReader().getName(); + w.write("Class: " + className + "\n"); + w.flush(); + + ci.enableFakeLineNumbers(10000); + + for (int m = 0; m < ci.getReader().getMethodCount(); m++) { + MethodData d = ci.visitMethod(m); + if (d != null) { + d.setHasChanged(); + + MethodEditor me = new MethodEditor(d); + me.beginPass(); + ExceptionHandler[][] handlers = me.getHandlers(); + boolean[] putDumperAt = new boolean[handlers.length]; + for (int i = 0; i < handlers.length; i++) { + for (int j = 0; j < handlers[i].length; j++) { + int offset = handlers[i][j].getHandler(); + if (!putDumperAt[offset]) { + putDumperAt[offset] = true; + me.insertBefore(offset, new MethodEditor.Patch() { + public void emitTo(Output w) { + w.emit(DupInstruction.make(0)); + w.emit(Util.makeInvoke(Throwable.class, "printStackTrace", new Class[0])); + } + }); + } + } + } + me.applyPatches(); + } + } + + if (ci.isChanged()) { + ClassWriter cw = ci.emitClass(); + instrumenter.outputModifiedClass(ci, cw); + } + } +} diff --git a/com.ibm.wala.shrike/src/com/ibm/wala/shrike/bench/Bench.java b/com.ibm.wala.shrike/src/com/ibm/wala/shrike/bench/Bench.java new file mode 100644 index 000000000..d40c5ad25 --- /dev/null +++ b/com.ibm.wala.shrike/src/com/ibm/wala/shrike/bench/Bench.java @@ -0,0 +1,191 @@ +/******************************************************************************* + * 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.FileWriter; +import java.io.PrintStream; +import java.io.Writer; + +import com.ibm.wala.shrikeBT.ConditionalBranchInstruction; +import com.ibm.wala.shrikeBT.ConstantInstruction; +import com.ibm.wala.shrikeBT.Constants; +import com.ibm.wala.shrikeBT.Disassembler; +import com.ibm.wala.shrikeBT.GetInstruction; +import com.ibm.wala.shrikeBT.Instruction; +import com.ibm.wala.shrikeBT.MethodData; +import com.ibm.wala.shrikeBT.MethodEditor; +import com.ibm.wala.shrikeBT.ReturnInstruction; +import com.ibm.wala.shrikeBT.ThrowInstruction; +import com.ibm.wala.shrikeBT.Util; +import com.ibm.wala.shrikeBT.MethodEditor.Output; +import com.ibm.wala.shrikeBT.analysis.Verifier; +import com.ibm.wala.shrikeBT.shrikeCT.CTDecoder; +import com.ibm.wala.shrikeBT.shrikeCT.ClassInstrumenter; +import com.ibm.wala.shrikeBT.shrikeCT.OfflineInstrumenter; +import com.ibm.wala.shrikeCT.ClassReader; +import com.ibm.wala.shrikeCT.ClassWriter; + +/** + * This is a demo class. + * + * Class files are taken as input arguments (or if there are none, from standard + * input). The methods in those files are instrumented: we insert a + * System.err.println() at ever method call, and a System.err.println() at every + * method entry. + * + * In Unix, I run it like this: java -cp ~/dev/shrike/shrike + * com.ibm.wala.shrikeBT.shrikeCT.tools.Bench test.jar -o output.jar + * + * The instrumented classes are placed in the directory "output" under the + * current directory. Disassembled code is written to the file "report" under + * the current directory. + */ +public class Bench { + private final static boolean disasm = true; + private final static boolean verify = true; + + private static OfflineInstrumenter instrumenter; + + private static boolean doEntry = true; + private static boolean doExit = false; + private static boolean doException = false; + + public static void main(String[] args) throws Exception { + for (int i = 0; i < 1; i++) { + instrumenter = new OfflineInstrumenter(); + + Writer w = new BufferedWriter(new FileWriter("report", false)); + + args = instrumenter.parseStandardArgs(args); + if (args.length > 0) { + if (args[0].equals("-doexit")) { + doExit = true; + } else if (args[0].equals("-doexception")) { + doExit = true; + doException = true; + } + } + instrumenter.setPassUnmodifiedClasses(true); + instrumenter.beginTraversal(); + ClassInstrumenter ci; + while ((ci = instrumenter.nextClass()) != null) { + doClass(ci, w); + } + instrumenter.close(); + } + } + + static final String fieldName = "_Bench_enable_trace"; + + // Keep these commonly used instructions around + static final Instruction getSysErr = Util.makeGet(System.class, "err"); + static final Instruction callPrintln = Util.makeInvoke(PrintStream.class, "println", new Class[] { String.class }); + + private static void doClass(final ClassInstrumenter ci, Writer w) throws Exception { + final String className = ci.getReader().getName(); + w.write("Class: " + className + "\n"); + w.flush(); + + for (int m = 0; m < ci.getReader().getMethodCount(); m++) { + MethodData d = ci.visitMethod(m); + + // d could be null, e.g., if the method is abstract or native + if (d != null) { + w.write("Instrumenting " + ci.getReader().getMethodName(m) + " " + ci.getReader().getMethodType(m) + ":\n"); + w.flush(); + + if (disasm) { + w.write("Initial ShrikeBT code:\n"); + (new Disassembler(d)).disassembleTo(w); + w.flush(); + } + + if (verify) { + Verifier v = new Verifier(d); + v.verify(); + } + + MethodEditor me = new MethodEditor(d); + me.beginPass(); + + if (doEntry) { + final String msg0 = "Entering call to " + Util.makeClass("L" + ci.getReader().getName() + ";") + "." + + ci.getReader().getMethodName(m); + final int noTraceLabel = me.allocateLabel(); + me.insertAtStart(new MethodEditor.Patch() { + public void emitTo(MethodEditor.Output w) { + w.emit(GetInstruction.make(Constants.TYPE_boolean, CTDecoder.convertClassToType(className), fieldName, true)); + w.emit(ConstantInstruction.make(0)); + w.emit(ConditionalBranchInstruction.make(Constants.TYPE_int, ConditionalBranchInstruction.Operator.EQ, noTraceLabel)); + w.emit(getSysErr); + w.emit(ConstantInstruction.makeString(msg0)); + w.emit(callPrintln); + w.emitLabel(noTraceLabel); + } + }); + } + if (doExit) { + final String msg0 = "Exiting call to " + Util.makeClass("L" + ci.getReader().getName() + ";") + "." + + ci.getReader().getMethodName(m); + Instruction[] instr = me.getInstructions(); + for (int i = 0; i < instr.length; i++) { + if (instr[i] instanceof ReturnInstruction) { + final int noTraceLabel = me.allocateLabel(); + me.insertBefore(i, new MethodEditor.Patch() { + public void emitTo(MethodEditor.Output w) { + w.emit(GetInstruction.make(Constants.TYPE_boolean, CTDecoder.convertClassToType(className), fieldName, true)); + w.emit(ConstantInstruction.make(0)); + w.emit(ConditionalBranchInstruction.make(Constants.TYPE_int, ConditionalBranchInstruction.Operator.EQ, noTraceLabel)); + w.emit(getSysErr); + w.emit(ConstantInstruction.makeString(msg0)); + w.emit(callPrintln); + w.emitLabel(noTraceLabel); + } + }); + } + } + } + if (doException) { + final String msg0 = "Exception exiting call to " + Util.makeClass("L" + ci.getReader().getName() + ";") + "." + + ci.getReader().getMethodName(m); + final int noTraceLabel = me.allocateLabel(); + me.addMethodExceptionHandler(null, new MethodEditor.Patch() { + public void emitTo(Output w) { + w.emit(GetInstruction.make(Constants.TYPE_boolean, CTDecoder.convertClassToType(className), fieldName, true)); + w.emit(ConstantInstruction.make(0)); + w.emit(ConditionalBranchInstruction.make(Constants.TYPE_int, ConditionalBranchInstruction.Operator.EQ, noTraceLabel)); + w.emit(getSysErr); + w.emit(ConstantInstruction.makeString(msg0)); + w.emit(callPrintln); + w.emitLabel(noTraceLabel); + w.emit(ThrowInstruction.make()); + } + }); + } + // this updates the data d + me.applyPatches(); + + if (disasm) { + w.write("Final ShrikeBT code:\n"); + (new Disassembler(d)).disassembleTo(w); + w.flush(); + } + } + } + + if (ci.isChanged()) { + ClassWriter cw = ci.emitClass(); + cw.addField(ClassReader.ACC_PUBLIC | ClassReader.ACC_STATIC, fieldName, Constants.TYPE_boolean, new ClassWriter.Element[0]); + instrumenter.outputModifiedClass(ci, cw); + } + } +} diff --git a/com.ibm.wala.shrike/src/com/ibm/wala/shrike/bench/InterfaceAnalyzer.java b/com.ibm.wala.shrike/src/com/ibm/wala/shrike/bench/InterfaceAnalyzer.java new file mode 100644 index 000000000..0ea4e140a --- /dev/null +++ b/com.ibm.wala.shrike/src/com/ibm/wala/shrike/bench/InterfaceAnalyzer.java @@ -0,0 +1,123 @@ +/******************************************************************************* + * 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 + * + * To change the template for this generated type comment go to Window - + * Preferences - Java - Code Generation - Code and Comments + */ +public class InterfaceAnalyzer { + final static class TypeStats { + int totalOccurrences; + int methodOccurrences; + int publicMethodOccurrences; + int foreignPublicMethodOccurrences; + int lastMUID; + } + + static HashMap typeStats = new HashMap(); + + public static void main(String[] args) throws Exception { + OfflineInstrumenter instrumenter = new OfflineInstrumenter(); + + 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 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); + } +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/src/com/ibm/wala/shrike/bench/Mangler.java b/com.ibm.wala.shrike/src/com/ibm/wala/shrike/bench/Mangler.java new file mode 100644 index 000000000..59405d9f5 --- /dev/null +++ b/com.ibm.wala.shrike/src/com/ibm/wala/shrike/bench/Mangler.java @@ -0,0 +1,206 @@ +/******************************************************************************* + * 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.File; +import java.io.FileWriter; +import java.io.Writer; +import java.util.Random; + +import com.ibm.wala.shrikeBT.ArrayStoreInstruction; +import com.ibm.wala.shrikeBT.ConditionalBranchInstruction; +import com.ibm.wala.shrikeBT.ConstantInstruction; +import com.ibm.wala.shrikeBT.Constants; +import com.ibm.wala.shrikeBT.Disassembler; +import com.ibm.wala.shrikeBT.DupInstruction; +import com.ibm.wala.shrikeBT.GetInstruction; +import com.ibm.wala.shrikeBT.LoadInstruction; +import com.ibm.wala.shrikeBT.MethodData; +import com.ibm.wala.shrikeBT.MethodEditor; +import com.ibm.wala.shrikeBT.PutInstruction; +import com.ibm.wala.shrikeBT.StoreInstruction; +import com.ibm.wala.shrikeBT.SwapInstruction; +import com.ibm.wala.shrikeBT.Util; +import com.ibm.wala.shrikeBT.MethodEditor.Output; +import com.ibm.wala.shrikeBT.analysis.Verifier; +import com.ibm.wala.shrikeBT.info.LocalAllocator; +import com.ibm.wala.shrikeBT.shrikeCT.ClassInstrumenter; +import com.ibm.wala.shrikeBT.shrikeCT.OfflineInstrumenter; +import com.ibm.wala.shrikeCT.ClassWriter; + +/** + * This is a demo class. + * + * Class files are taken as input arguments (or if there are none, from standard + * input). The methods in those files are instrumented: we insert a + * System.err.println() at ever method call, and a System.err.println() at every + * method entry. + * + * In Unix, I run it like this: java -cp ~/dev/shrike/shrike + * com.ibm.wala.shrikeBT.shrikeCT.tools.Bench test.jar -o output.jar + * + * The instrumented classes are placed in the directory "output" under the + * current directory. Disassembled code is written to the file "report" under + * the current directory. + */ +public class Mangler { + private static OfflineInstrumenter instrumenter; + private static final boolean verify = true; + private static final boolean disasm = true; + + public static void main(String[] args) throws Exception { + for (int i = 0; i < 1; i++) { + instrumenter = new OfflineInstrumenter(); + + Writer w = new BufferedWriter(new FileWriter("report", false)); + + args = instrumenter.parseStandardArgs(args); + int seed; + try { + seed = Integer.parseInt(args[0]); + } catch (NumberFormatException ex) { + System.err.println("Invalid number: " + args[0]); + return; + } + + Random r = new Random(seed); + instrumenter.setPassUnmodifiedClasses(true); + instrumenter.beginTraversal(); + instrumenter.setOutputJar(new File("output.jar")); + ClassInstrumenter ci; + while ((ci = instrumenter.nextClass()) != null) { + doClass(ci, w, r); + } + instrumenter.close(); + } + } + + private static void doClass(final ClassInstrumenter ci, Writer w, final Random r) throws Exception { + final String className = ci.getReader().getName(); + w.write("Class: " + className + "\n"); + w.flush(); + + for (int m = 0; m < ci.getReader().getMethodCount(); m++) { + MethodData d = ci.visitMethod(m); + + // d could be null, e.g., if the method is abstract or native + if (d != null) { + w.write("Instrumenting " + ci.getReader().getMethodName(m) + " " + ci.getReader().getMethodType(m) + ":\n"); + w.flush(); + + if (disasm) { + w.write("Initial ShrikeBT code:\n"); + (new Disassembler(d)).disassembleTo(w); + w.flush(); + } + + if (verify) { + Verifier v = new Verifier(d); + v.verify(); + } + + final int passes = r.nextInt(4) + 1; + + for (int i = 0; i < passes; i++) { + final boolean doGet = true; // r.nextBoolean(); + final boolean doPut = true; // r.nextBoolean(); + final boolean doArrayStore = true; // r.nextBoolean(); + final int tmpInt = LocalAllocator.allocate(d, "I"); + final int tmpAny = LocalAllocator.allocate(d); + + final MethodEditor me = new MethodEditor(d); + me.beginPass(); + + me.visitInstructions(new MethodEditor.Visitor() { + public void visitGet(GetInstruction instruction) { + if (doGet && !instruction.isStatic()) { + insertBefore(new MethodEditor.Patch() { + public void emitTo(Output w) { + w.emit(DupInstruction.make(0)); + } + }); + insertAfter(new MethodEditor.Patch() { + public void emitTo(Output w) { + w.emit(SwapInstruction.make()); + w.emit(Util.makePut(Slots.class, "o")); + } + }); + } + } + + public void visitPut(PutInstruction instruction) { + if (doPut && !instruction.isStatic()) { + insertBefore(new MethodEditor.Patch() { + public void emitTo(Output w) { + w.emit(SwapInstruction.make()); + w.emit(DupInstruction.make(1)); + w.emit(SwapInstruction.make()); + } + }); + insertAfter(new MethodEditor.Patch() { + public void emitTo(Output w) { + w.emit(Util.makePut(Slots.class, "o")); + } + }); + } + } + + public void visitArrayStore(final ArrayStoreInstruction instruction) { + if (doArrayStore) { + final int label = me.allocateLabel(); + insertBefore(new MethodEditor.Patch() { + public void emitTo(Output w) { + String t = Util.getStackType(instruction.getType()); + w.emit(StoreInstruction.make(t, tmpAny)); + w.emit(StoreInstruction.make(Constants.TYPE_int, tmpInt)); + w.emit(DupInstruction.make(0)); + w.emit(LoadInstruction.make(Constants.TYPE_int, tmpInt)); + w.emit(LoadInstruction.make(t, tmpAny)); + if (t.equals(Constants.TYPE_int)) { + w.emit(DupInstruction.make(0)); + w.emit(ConstantInstruction.make(0)); + w.emit(ConditionalBranchInstruction.make(t, ConditionalBranchInstruction.Operator.EQ, label)); + w.emit(DupInstruction.make(0)); + w.emit(Util.makePut(Slots.class, "i")); + w.emitLabel(label); + } + } + }); + insertAfter(new MethodEditor.Patch() { + public void emitTo(Output w) { + w.emit(Util.makePut(Slots.class, "o")); + w.emit(LoadInstruction.make(Constants.TYPE_int, tmpInt)); + w.emit(Util.makePut(Slots.class, "i")); + } + }); + } + } + }); + + // this updates the data d + me.applyPatches(); + } + + if (disasm) { + w.write("Final ShrikeBT code:\n"); + (new Disassembler(d)).disassembleTo(w); + w.flush(); + } + } + } + + if (ci.isChanged()) { + ClassWriter cw = ci.emitClass(); + instrumenter.outputModifiedClass(ci, cw); + } + } +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/src/com/ibm/wala/shrike/bench/Slots.java b/com.ibm.wala.shrike/src/com/ibm/wala/shrike/bench/Slots.java new file mode 100644 index 000000000..03606b5e7 --- /dev/null +++ b/com.ibm.wala.shrike/src/com/ibm/wala/shrike/bench/Slots.java @@ -0,0 +1,19 @@ +/******************************************************************************* + * 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; + +/** + * @author roca@us.ibm.com + */ +public class Slots { + public static Object o; + public static int i; +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/src/com/ibm/wala/shrike/bench/Statistics.java b/com.ibm.wala.shrike/src/com/ibm/wala/shrike/bench/Statistics.java new file mode 100644 index 000000000..76eda5961 --- /dev/null +++ b/com.ibm.wala.shrike/src/com/ibm/wala/shrike/bench/Statistics.java @@ -0,0 +1,108 @@ +/******************************************************************************* + * 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.FileWriter; +import java.io.Writer; + +import com.ibm.wala.shrikeBT.Constants; +import com.ibm.wala.shrikeBT.Instruction; +import com.ibm.wala.shrikeBT.InvokeInstruction; +import com.ibm.wala.shrikeBT.MethodData; +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; + +/** + * This is a demo class. + * + * Class files are taken as input arguments (or if there are none, from standard + * input). The methods in those files are instrumented: we insert a + * System.err.println() at ever method call, and a System.err.println() at every + * method entry. + * + * In Unix, I run it like this: java -cp ~/dev/shrike/shrike + * com.ibm.wala.shrikeBT.shrikeCT.tools.Bench test.jar -o output.jar + * + * The instrumented classes are placed in the directory "output" under the + * current directory. Disassembled code is written to the file "report" under + * the current directory. + */ +public class Statistics { + private static OfflineInstrumenter instrumenter; + + public static void main(String[] args) throws Exception { + for (int i = 0; i < 1; i++) { + instrumenter = new OfflineInstrumenter(); + + Writer w = new BufferedWriter(new FileWriter("report", false)); + + args = instrumenter.parseStandardArgs(args); + + instrumenter.beginTraversal(); + ClassInstrumenter ci; + while ((ci = instrumenter.nextClass()) != null) { + doClass(ci, w); + } + instrumenter.close(); + w.close(); + } + } + + private static void doClass(final ClassInstrumenter ci, Writer w) throws Exception { + ClassReader cr = ci.getReader(); + final String className = cr.getName(); + w.write("Class: " + className + "\n"); + + boolean allPrivateConstructors = true; + boolean methodCallsConstructor = false; + boolean classInitCallsConstructor = false; + + for (int m = 0; m < cr.getMethodCount(); m++) { + MethodData d = ci.visitMethod(m); + + // d could be null, e.g., if the method is abstract or native + if (d != null) { + if (d.getName().equals("")) { + int f = cr.getMethodAccessFlags(m); + if ((f & Constants.ACC_PRIVATE) == 0 + && ((f & Constants.ACC_PROTECTED) == 0 || (cr.getAccessFlags() & Constants.ACC_FINAL) == 0)) { + allPrivateConstructors = false; + } + } + + int constructorCalls = 0; + Instruction[] instrs = d.getInstructions(); + for (int i = 0; i < instrs.length; i++) { + if (instrs[i] instanceof InvokeInstruction) { + InvokeInstruction invoke = (InvokeInstruction) instrs[i]; + if (invoke.getMethodName().equals("") && invoke.getClassType().equals(Util.makeType(className))) { + constructorCalls++; + } + } + } + if (!d.getName().equals("") && !d.getName().equals("")) { + if (constructorCalls > 0) { + methodCallsConstructor = true; + } + } else if (d.getName().equals("")) { + classInitCallsConstructor = true; + } + } + } + + if (allPrivateConstructors && !methodCallsConstructor && classInitCallsConstructor) { + w.write("Restricted Creation\n"); + } + } +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/src/com/ibm/wala/shrike/copywriter/CopyWriter.java b/com.ibm.wala.shrike/src/com/ibm/wala/shrike/copywriter/CopyWriter.java new file mode 100644 index 000000000..c6c05d2b7 --- /dev/null +++ b/com.ibm.wala.shrike/src/com/ibm/wala/shrike/copywriter/CopyWriter.java @@ -0,0 +1,341 @@ +/******************************************************************************* + * 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.copywriter; + +import java.io.OutputStreamWriter; +import java.io.Writer; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.zip.ZipEntry; + +import com.ibm.wala.shrikeBT.Compiler; +import com.ibm.wala.shrikeBT.MethodData; +import com.ibm.wala.shrikeBT.Decoder.InvalidBytecodeException; +import com.ibm.wala.shrikeBT.shrikeCT.CTCompiler; +import com.ibm.wala.shrikeBT.shrikeCT.CTDecoder; +import com.ibm.wala.shrikeBT.shrikeCT.ClassInstrumenter; +import com.ibm.wala.shrikeBT.shrikeCT.OfflineInstrumenter; +import com.ibm.wala.shrikeCT.ClassReader; +import com.ibm.wala.shrikeCT.ClassWriter; +import com.ibm.wala.shrikeCT.CodeReader; +import com.ibm.wala.shrikeCT.CodeWriter; +import com.ibm.wala.shrikeCT.ConstantPoolParser; +import com.ibm.wala.shrikeCT.ConstantValueReader; +import com.ibm.wala.shrikeCT.ConstantValueWriter; +import com.ibm.wala.shrikeCT.ExceptionsReader; +import com.ibm.wala.shrikeCT.ExceptionsWriter; +import com.ibm.wala.shrikeCT.InnerClassesReader; +import com.ibm.wala.shrikeCT.InnerClassesWriter; +import com.ibm.wala.shrikeCT.InvalidClassFileException; +import com.ibm.wala.shrikeCT.LocalVariableTableReader; +import com.ibm.wala.shrikeCT.LocalVariableTableWriter; +import com.ibm.wala.shrikeCT.SourceFileReader; +import com.ibm.wala.shrikeCT.SourceFileWriter; +import com.ibm.wala.shrikeCT.ClassReader.AttrIterator; +import com.ibm.wala.shrikeCT.ClassWriter.Element; + +public class CopyWriter { + private static final String USAGE = "IBM CopyWriter Tool\n" + "This tool takes the following command line options:\n" + + " ... Process the classes from these jars\n" + + " -o Put the resulting classes into \n" + + " -c Make the copyright string be\n" + + " '\u00A9 Copyright '"; + private static OfflineInstrumenter instrumenter; + public static String copyright; + public static final String copyrightAttrName = "com.ibm.Copyright"; + + private int replaceWith; + private int replace; + + static class UnknownAttributeException extends Exception { + private static final long serialVersionUID = 8845177787110364793L; + + UnknownAttributeException(String t) { + super("Attribute '" + t + "' not understood"); + } + } + + public static void main(String[] args) throws Exception { + if (args.length == 0) { + System.err.println(USAGE); + System.exit(1); + } + + for (int i = 0; i < args.length - 1; i++) { + if (args[i].equals("-c")) { + copyright = "\u00A9 Copyright " + args[i + 1]; + String[] newArgs = new String[args.length - 2]; + System.arraycopy(args, 0, newArgs, 0, i); + System.arraycopy(args, i + 2, newArgs, i, newArgs.length - i); + args = newArgs; + break; + } + } + if (copyright == null) { + System.err.println(USAGE); + System.exit(1); + } + + final ArrayList entries = new ArrayList(); + + instrumenter = new OfflineInstrumenter(); + instrumenter.setManifestBuilder(new OfflineInstrumenter.ManifestBuilder() { + public void addEntry(ZipEntry ze) { + entries.add(ze); + } + }); + instrumenter.parseStandardArgs(args); + instrumenter.setJARComment(copyright); + instrumenter.beginTraversal(); + ClassInstrumenter ci; + CopyWriter cw = new CopyWriter(); + while ((ci = instrumenter.nextClass()) != null) { + try { + cw.doClass(ci); + } catch (UnknownAttributeException ex) { + System.err.println(ex.getMessage() + " in " + instrumenter.getLastClassResourceName()); + } + } + + instrumenter.writeUnmodifiedClasses(); + + Writer w = new OutputStreamWriter(instrumenter.addOutputJarEntry(new ZipEntry("IBM-Copyright"))); + w.write(copyright + "\n"); + for (Iterator iter = entries.iterator(); iter.hasNext();) { + ZipEntry ze = iter.next(); + w.write(" " + ze.getName() + "\n"); + } + w.write(copyright + "\n"); + w.flush(); + instrumenter.endOutputJarEntry(); + + instrumenter.close(); + } + + private int transformCPIndex(int i) { + if (i == replace) { + return replaceWith; + } else { + return i; + } + } + + private Element transformAttribute(ClassReader cr, int m, ClassWriter w, AttrIterator iter) throws InvalidClassFileException, + UnknownAttributeException, InvalidBytecodeException { + String name = iter.getName(); + + boolean needTransform = true; + if (name.equals("Synthetic") || name.equals("Deprecated") || name.equals("LineNumberTable")) { + needTransform = false; + } + + int offset = iter.getRawOffset(); + int end = offset + iter.getRawSize(); + + if (needTransform) { + needTransform = false; + for (int i = offset; i + 1 < end; i++) { + if (cr.getUShort(i) == replace) { + break; + } + } + } + + if (!needTransform) { + return new ClassWriter.RawElement(cr.getBytes(), offset, end - offset); + } + + if (name.equals("Code")) { + CodeReader r = new CodeReader(iter); + CTDecoder decoder = new CTDecoder(r); + decoder.decode(); + MethodData md = new MethodData(decoder, cr.getMethodAccessFlags(m), CTDecoder.convertClassToType(cr.getName()), cr + .getMethodName(m), cr.getMethodType(m)); + CTCompiler compiler = new CTCompiler(w, md); + compiler.compile(); + if (compiler.getAuxiliaryMethods().length > 0) + throw new Error("Where did this auxiliary method come from?"); + Compiler.Output out = compiler.getOutput(); + CodeWriter cw = new CodeWriter(w); + cw.setMaxLocals(out.getMaxLocals()); + cw.setMaxStack(out.getMaxStack()); + cw.setCode(out.getCode()); + cw.setRawHandlers(out.getRawHandlers()); + ClassReader.AttrIterator iterator = new ClassReader.AttrIterator(); + r.initAttributeIterator(iterator); + cw.setAttributes(collectAttributes(cr, m, w, iterator)); + return cw; + } else if (name.equals("ConstantValue")) { + ConstantValueReader r = new ConstantValueReader(iter); + ConstantValueWriter cw = new ConstantValueWriter(w); + cw.setValueCPIndex(transformCPIndex(r.getValueCPIndex())); + return cw; + } else if (name.equals("SourceFile")) { + SourceFileReader r = new SourceFileReader(iter); + SourceFileWriter cw = new SourceFileWriter(w); + cw.setSourceFileCPIndex(transformCPIndex(r.getSourceFileCPIndex())); + return cw; + } else if (name.equals("LocalVariableTableReader")) { + LocalVariableTableReader lr = new LocalVariableTableReader(iter); + LocalVariableTableWriter lw = new LocalVariableTableWriter(w); + int[] table = lr.getRawTable(); + for (int i = 0; i < table.length; i += 5) { + table[i + 2] = transformCPIndex(table[i + 2]); + table[i + 3] = transformCPIndex(table[i + 3]); + } + lw.setRawTable(table); + return lw; + } else if (name.equals("Exceptions")) { + ExceptionsReader lr = new ExceptionsReader(iter); + ExceptionsWriter lw = new ExceptionsWriter(w); + int[] table = lr.getRawTable(); + for (int i = 0; i < table.length; i++) { + table[i] = transformCPIndex(table[i]); + } + lw.setRawTable(table); + return lw; + } else if (name.equals("InnerClasses")) { + InnerClassesReader lr = new InnerClassesReader(iter); + InnerClassesWriter lw = new InnerClassesWriter(w); + int[] table = lr.getRawTable(); + for (int i = 0; i < table.length; i += 4) { + table[i] = transformCPIndex(table[i]); + table[i + 1] = transformCPIndex(table[i + 1]); + table[i + 2] = transformCPIndex(table[i + 2]); + } + lw.setRawTable(table); + return lw; + } + + throw new UnknownAttributeException(name); + } + + private Element[] collectAttributes(ClassReader cr, int m, ClassWriter w, AttrIterator iter) throws InvalidClassFileException, + UnknownAttributeException, InvalidBytecodeException { + Element[] elems = new Element[iter.getRemainingAttributesCount()]; + for (int i = 0; i < elems.length; i++) { + elems[i] = transformAttribute(cr, m, w, iter); + iter.advance(); + } + return elems; + } + + private int copyEntry(ConstantPoolParser cp, ClassWriter w, int i) throws InvalidClassFileException { + byte t = cp.getItemType(i); + switch (t) { + case ClassReader.CONSTANT_String: + return w.addCPString(cp.getCPString(i)); + case ClassReader.CONSTANT_Class: + return w.addCPClass(cp.getCPClass(i)); + case ClassReader.CONSTANT_FieldRef: + return w.addCPFieldRef(cp.getCPRefClass(i), cp.getCPRefName(i), cp.getCPRefType(i)); + case ClassReader.CONSTANT_InterfaceMethodRef: + return w.addCPInterfaceMethodRef(cp.getCPRefClass(i), cp.getCPRefName(i), cp.getCPRefType(i)); + case ClassReader.CONSTANT_MethodRef: + return w.addCPMethodRef(cp.getCPRefClass(i), cp.getCPRefName(i), cp.getCPRefType(i)); + case ClassReader.CONSTANT_NameAndType: + return w.addCPNAT(cp.getCPNATName(i), cp.getCPNATType(i)); + case ClassReader.CONSTANT_Integer: + return w.addCPInt(cp.getCPInt(i)); + case ClassReader.CONSTANT_Float: + return w.addCPFloat(cp.getCPFloat(i)); + case ClassReader.CONSTANT_Long: + return w.addCPLong(cp.getCPLong(i)); + case ClassReader.CONSTANT_Double: + return w.addCPDouble(cp.getCPDouble(i)); + case ClassReader.CONSTANT_Utf8: + return w.addCPUtf8(cp.getCPUtf8(i)); + } + return -1; + } + + private void doClass(final ClassInstrumenter ci) throws Exception { + /* + * Our basic strategy is to make the first element of the constant pool be + * the copyright string (as a UTF8 constant pool item). This requires us to + * parse and emit any class data which might refer to that constant pool + * item (#1). We will assume that any attribute which refers to that + * constant pool item must contain the byte sequence '00 01', so we can just + * copy over any attributes which don't contain that byte sequence. If we + * detect an unknown attribute type containing the sequence '00 01', then we + * will abort. + */ + ClassReader cr = ci.getReader(); + ClassWriter w = new ClassWriter(); + + // Make sure that when we're moving over the old constant pool, + // anytime we add a new entry it really is added and we don't just + // reuse an existing entry. + w.setForceAddCPEntries(true); + + // Make the first string in the constant pool be the copyright string + int r = w.addCPUtf8(copyright); + if (r != 1) + throw new Error("Invalid constant pool index: " + r); + + // Now add the rest of the CP entries + ConstantPoolParser cp = cr.getCP(); + int CPCount = cp.getItemCount(); + + if (1 < CPCount) { + switch (cp.getItemType(1)) { + case ClassReader.CONSTANT_Long: + case ClassReader.CONSTANT_Double: + // item 1 is a double-word item, so the next real item is at 3 + // to make sure item 3 is allocated at index 3, we'll need to + // insert a dummy entry at index 2 + r = w.addCPUtf8(""); + if (r != 2) + throw new Error("Invalid constant pool index for dummy: " + r); + break; + } + } + for (int i = 2; i < CPCount; i++) { + r = copyEntry(cp, w, i); + if (r != -1 && r != i) + throw new Error("Invalid constant pool index allocated: " + r + ", expected " + i); + } + w.setForceAddCPEntries(false); + + // add CP entry we replaced + replaceWith = copyEntry(cp, w, 1); + replace = 1; + + // emit class + w.setMajorVersion(cr.getMajorVersion()); + w.setMinorVersion(cr.getMinorVersion()); + w.setAccessFlags(cr.getAccessFlags()); + w.setName(cr.getName()); + w.setSuperName(cr.getSuperName()); + w.setInterfaceNames(cr.getInterfaceNames()); + + ClassReader.AttrIterator iter = new ClassReader.AttrIterator(); + + int fieldCount = cr.getFieldCount(); + for (int i = 0; i < fieldCount; i++) { + cr.initFieldAttributeIterator(i, iter); + w.addField(cr.getFieldAccessFlags(i), cr.getFieldName(i), cr.getFieldType(i), collectAttributes(cr, i, w, iter)); + } + + int methodCount = cr.getMethodCount(); + for (int i = 0; i < methodCount; i++) { + cr.initMethodAttributeIterator(i, iter); + w.addMethod(cr.getMethodAccessFlags(i), cr.getMethodName(i), cr.getMethodType(i), collectAttributes(cr, i, w, iter)); + } + + cr.initClassAttributeIterator(iter); + for (; iter.isValid(); iter.advance()) { + w.addClassAttribute(transformAttribute(cr, 0, w, iter)); + } + + instrumenter.outputModifiedClass(ci, w); + } +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/src/com/ibm/wala/shrike/tools/ExtractMatchingClasses.java b/com.ibm.wala.shrike/src/com/ibm/wala/shrike/tools/ExtractMatchingClasses.java new file mode 100644 index 000000000..667df5e99 --- /dev/null +++ b/com.ibm.wala.shrike/src/com/ibm/wala/shrike/tools/ExtractMatchingClasses.java @@ -0,0 +1,66 @@ +/******************************************************************************* + * 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.tools; + +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.Enumeration; +import java.util.jar.JarEntry; +import java.util.jar.JarFile; +import java.util.jar.JarOutputStream; + +public class ExtractMatchingClasses { + private static boolean matchEntry(JarFile[] matches, JarEntry e) { + for (int i = 0; i < matches.length; i++) { + if (matches[i].getEntry(e.getName()) != null) { + return true; + } + } + return false; + } + + private static void readFully(InputStream s, byte[] b) throws IOException { + int offset = 0; + while (offset < b.length) { + int read = s.read(b, offset, b.length - offset); + offset += read; + } + } + + public static void main(String[] args) throws Exception { + String in = args[0]; + String out = args[1]; + String[] match = new String[args.length - 2]; + System.arraycopy(args, 2, match, 0, match.length); + + JarFile inJar = new JarFile(in); + JarOutputStream outJar = new JarOutputStream(new FileOutputStream(out)); + JarFile[] matches = new JarFile[match.length]; + for (int i = 0; i < match.length; i++) { + matches[i] = new JarFile(match[i]); + } + + for (Enumeration e = inJar.entries(); e.hasMoreElements();) { + JarEntry entry = (JarEntry) e.nextElement(); + + if (matchEntry(matches, entry)) { + outJar.putNextEntry(entry); + byte[] data = new byte[(int) entry.getSize()]; + InputStream stream = inJar.getInputStream(entry); + readFully(stream, data); + outJar.write(data); + outJar.flush(); + } + } + outJar.close(); + } +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/ArrayLengthInstruction.java b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/ArrayLengthInstruction.java new file mode 100644 index 000000000..9a86a3c65 --- /dev/null +++ b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/ArrayLengthInstruction.java @@ -0,0 +1,60 @@ +/******************************************************************************* + * 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.shrikeBT; + +/** + * This class represents arraylength instructions. + */ +final public class ArrayLengthInstruction extends Instruction { + protected ArrayLengthInstruction() { + opcode = (byte) OP_arraylength; + } + + private static ArrayLengthInstruction preallocated = new ArrayLengthInstruction(); + + public static ArrayLengthInstruction make() { + return preallocated; + } + + public boolean equals(Object o) { + return o instanceof ArrayLengthInstruction; + } + + public int hashCode() { + return 3180901; + } + + public int getPoppedCount() { + return 1; + } + + public String getPushedType(String[] types) { + return Constants.TYPE_int; + } + + public byte getPushedWordSize() { + return 1; + } + + public void visit(Visitor v) { + v.visitArrayLength(this); + } + + public String toString() { + return "ArrayLength()"; + } + /* (non-Javadoc) + * @see com.ibm.domo.cfg.IInstruction#isPEI() + */ + public boolean isPEI() { + return true; + } +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/ArrayLoadInstruction.java b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/ArrayLoadInstruction.java new file mode 100644 index 000000000..0ce708282 --- /dev/null +++ b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/ArrayLoadInstruction.java @@ -0,0 +1,93 @@ +/******************************************************************************* + * 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.shrikeBT; + +/** + * This class represents the ?aload instructions. + */ +final public class ArrayLoadInstruction extends Instruction { + protected ArrayLoadInstruction(short opcode) { + this.opcode = opcode; + } + + private final static ArrayLoadInstruction[] preallocated = preallocate(); + + private static ArrayLoadInstruction[] preallocate() { + ArrayLoadInstruction[] r = new ArrayLoadInstruction[OP_saload - OP_iaload + 2]; + for (short i = OP_iaload; i <= OP_saload; i++) { + r[i - OP_iaload] = new ArrayLoadInstruction(i); + } + r[OP_saload - OP_iaload + 1] = r[OP_baload - OP_iaload]; + return r; + } + + public static ArrayLoadInstruction make(String type) { + int i = Util.getTypeIndex(type); + if (i < 0 || i > TYPE_boolean_index) { + throw new IllegalArgumentException("Invalid type " + type + " for ArrayLoadInstruction"); + } + return preallocated[i]; + } + + public boolean equals(Object o) { + if (o instanceof ArrayLoadInstruction) { + ArrayLoadInstruction i = (ArrayLoadInstruction) o; + return i.opcode == opcode; + } else { + return false; + } + } + + public int hashCode() { + return opcode + 9109101; + } + + public int getPoppedCount() { + return 2; + } + + public String toString() { + return "ArrayLoad(" + getType() + ")"; + } + + public String getPushedType(String[] types) { + if (types == null) { + return getType(); + } else { + String t = types[1]; + if (t.startsWith("[")) { + return t.substring(1); + } else if (t.equals(TYPE_null)) { + return TYPE_null; + } else { + return TYPE_unknown; + } + } + } + + public byte getPushedWordSize() { + return Util.getWordSize(getType()); + } + + public String getType() { + return Constants.indexedTypes[opcode - OP_iaload]; + } + + public void visit(Visitor v) { + v.visitArrayLoad(this); + } + /* (non-Javadoc) + * @see com.ibm.domo.cfg.IInstruction#isPEI() + */ + public boolean isPEI() { + return true; + } +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/ArrayStoreInstruction.java b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/ArrayStoreInstruction.java new file mode 100644 index 000000000..85e60229d --- /dev/null +++ b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/ArrayStoreInstruction.java @@ -0,0 +1,74 @@ +/******************************************************************************* + * 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.shrikeBT; + +/** + * This class represents the ?astore instructions. + */ +final public class ArrayStoreInstruction extends Instruction { + protected ArrayStoreInstruction(short opcode) { + this.opcode = opcode; + } + + private final static ArrayStoreInstruction[] preallocated = preallocate(); + + private static ArrayStoreInstruction[] preallocate() { + ArrayStoreInstruction[] r = new ArrayStoreInstruction[OP_sastore - OP_iastore + 2]; + for (short i = OP_iastore; i <= OP_sastore; i++) { + r[i - OP_iastore] = new ArrayStoreInstruction(i); + } + r[OP_sastore - OP_iastore + 1] = r[OP_baload - OP_iaload]; + return r; + } + + public static ArrayStoreInstruction make(String type) { + int i = Util.getTypeIndex(type); + if (i < 0 || i > TYPE_boolean_index) { + throw new IllegalArgumentException("Invalid type " + type + " for ArrayStoreInstruction"); + } + return preallocated[i]; + } + + public boolean equals(Object o) { + if (o instanceof ArrayStoreInstruction) { + ArrayStoreInstruction i = (ArrayStoreInstruction) o; + return i.opcode == opcode; + } else { + return false; + } + } + + public int hashCode() { + return opcode + 148791; + } + + public int getPoppedCount() { + return 3; + } + + public String getType() { + return Decoder.indexedTypes[opcode - OP_iastore]; + } + + public String toString() { + return "ArrayStore(" + getType() + ")"; + } + + public void visit(Visitor v) { + v.visitArrayStore(this); + } + /* (non-Javadoc) + * @see com.ibm.domo.cfg.IInstruction#isPEI() + */ + public boolean isPEI() { + return true; + } +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/BinaryOpInstruction.java b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/BinaryOpInstruction.java new file mode 100644 index 000000000..3130c10ab --- /dev/null +++ b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/BinaryOpInstruction.java @@ -0,0 +1,130 @@ +/******************************************************************************* + * 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.shrikeBT; + +/** + * This class represents binary operator instructions for which the operands and + * the result all have the same type. + */ +final public class BinaryOpInstruction extends Instruction { + public interface IOperator {} + + public enum Operator implements IOperator { + ADD, SUB, MUL, DIV, REM, AND, OR, XOR; + + @Override + public String toString() { + return super.toString().toLowerCase(); + } + } + + protected BinaryOpInstruction(short opcode) { + this.opcode = opcode; + } + + private final static BinaryOpInstruction[] arithmeticOps = preallocateArithmeticOps(); + private final static BinaryOpInstruction[] logicalOps = preallocateLogicalOps(); + + private static BinaryOpInstruction[] preallocateArithmeticOps() { + BinaryOpInstruction[] r = new BinaryOpInstruction[OP_drem - OP_iadd + 1]; + for (short i = OP_iadd; i <= OP_drem; i++) { + r[i - OP_iadd] = new BinaryOpInstruction(i); + } + return r; + } + + private static BinaryOpInstruction[] preallocateLogicalOps() { + BinaryOpInstruction[] r = new BinaryOpInstruction[OP_lxor - OP_iand + 1]; + for (short i = OP_iand; i <= OP_lxor; i++) { + r[i - OP_iand] = new BinaryOpInstruction(i); + } + return r; + } + + public static BinaryOpInstruction make(String type, Operator operator) { + int t = Util.getTypeIndex(type); + if (t < 0) { + throw new IllegalArgumentException("Invalid type for BinaryOp: " + type); + } + + if (operator.compareTo(Operator.REM) <= 0) { + if (t > TYPE_double_index) { + throw new IllegalArgumentException("Invalid type for BinaryOp: " + type); + } + return arithmeticOps[(operator.ordinal() - Operator.ADD.ordinal()) * 4 + t]; + } else { + if (t > TYPE_long_index) { + throw new IllegalArgumentException("Cannot use logical binaryOps on floating point type: " + type); + } + return logicalOps[(operator.ordinal() - Operator.AND.ordinal()) * 2 + t]; + } + } + + public boolean equals(Object o) { + if (o instanceof BinaryOpInstruction) { + BinaryOpInstruction i = (BinaryOpInstruction) o; + return i.opcode == opcode; + } else { + return false; + } + } + + /** + * don't call this unless you really know what you're doing + */ + public Operator getOperator() { + if (opcode < OP_iand) { + return Operator.values()[(opcode - OP_iadd) / 4]; + } else { + return Operator.values()[(opcode - OP_iand) / 2]; + } + } + + public int hashCode() { + return opcode + 13901901; + } + + public int getPoppedCount() { + return 2; + } + + public String getPushedType(String[] types) { + return getType(); + } + + public byte getPushedWordSize() { + return Util.getWordSize(getType()); + } + + public String getType() { + int t; + if (opcode < OP_iand) { + t = (opcode - OP_iadd) & 3; + } else { + t = (opcode - OP_iand) & 1; + } + return indexedTypes[t]; + } + + public void visit(Visitor v) { + v.visitBinaryOp(this); + } + + public String toString() { + return "BinaryOp(" + getType() + "," + getOperator() + ")"; + } + /* (non-Javadoc) + * @see com.ibm.domo.cfg.IInstruction#isPEI() + */ + public boolean isPEI() { + return opcode == Constants.OP_idiv; + } +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/BytecodeConstants.java b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/BytecodeConstants.java new file mode 100644 index 000000000..19bedfd40 --- /dev/null +++ b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/BytecodeConstants.java @@ -0,0 +1,649 @@ +/******************************************************************************* + * 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.shrikeBT; + +/** + * Information about java byte codes that appear in the "code" attribute + * of a .class file. + * + * @author Bowen Alpern + * @author Derek Lieber + * @author Stephen Fink + */ +public interface BytecodeConstants { + + // The following mnemonics are defined in Chapter 10 of The Java Virtual Machine Specification. + // + public static final int JBC_nop = 0; + public static final int JBC_aconst_null = 1; + public static final int JBC_iconst_m1 = 2; + public static final int JBC_iconst_0 = 3; + public static final int JBC_iconst_1 = 4; + public static final int JBC_iconst_2 = 5; + public static final int JBC_iconst_3 = 6; + public static final int JBC_iconst_4 = 7; + public static final int JBC_iconst_5 = 8; + public static final int JBC_lconst_0 = 9; + public static final int JBC_lconst_1 = 10; + public static final int JBC_fconst_0 = 11; + public static final int JBC_fconst_1 = 12; + public static final int JBC_fconst_2 = 13; + public static final int JBC_dconst_0 = 14; + public static final int JBC_dconst_1 = 15; + public static final int JBC_bipush = 16; + public static final int JBC_sipush = 17; + public static final int JBC_ldc = 18; + public static final int JBC_ldc_w = 19; + public static final int JBC_ldc2_w = 20; + public static final int JBC_iload = 21; + public static final int JBC_lload = 22; + public static final int JBC_fload = 23; + public static final int JBC_dload = 24; + public static final int JBC_aload = 25; + public static final int JBC_iload_0 = 26; + public static final int JBC_iload_1 = 27; + public static final int JBC_iload_2 = 28; + public static final int JBC_iload_3 = 29; + public static final int JBC_lload_0 = 30; + public static final int JBC_lload_1 = 31; + public static final int JBC_lload_2 = 32; + public static final int JBC_lload_3 = 33; + public static final int JBC_fload_0 = 34; + public static final int JBC_fload_1 = 35; + public static final int JBC_fload_2 = 36; + public static final int JBC_fload_3 = 37; + public static final int JBC_dload_0 = 38; + public static final int JBC_dload_1 = 39; + public static final int JBC_dload_2 = 40; + public static final int JBC_dload_3 = 41; + public static final int JBC_aload_0 = 42; + public static final int JBC_aload_1 = 43; + public static final int JBC_aload_2 = 44; + public static final int JBC_aload_3 = 45; + public static final int JBC_iaload = 46; + public static final int JBC_laload = 47; + public static final int JBC_faload = 48; + public static final int JBC_daload = 49; + public static final int JBC_aaload = 50; + public static final int JBC_baload = 51; + public static final int JBC_caload = 52; + public static final int JBC_saload = 53; + public static final int JBC_istore = 54; + public static final int JBC_lstore = 55; + public static final int JBC_fstore = 56; + public static final int JBC_dstore = 57; + public static final int JBC_astore = 58; + public static final int JBC_istore_0 = 59; + public static final int JBC_istore_1 = 60; + public static final int JBC_istore_2 = 61; + public static final int JBC_istore_3 = 62; + public static final int JBC_lstore_0 = 63; + public static final int JBC_lstore_1 = 64; + public static final int JBC_lstore_2 = 65; + public static final int JBC_lstore_3 = 66; + public static final int JBC_fstore_0 = 67; + public static final int JBC_fstore_1 = 68; + public static final int JBC_fstore_2 = 69; + public static final int JBC_fstore_3 = 70; + public static final int JBC_dstore_0 = 71; + public static final int JBC_dstore_1 = 72; + public static final int JBC_dstore_2 = 73; + public static final int JBC_dstore_3 = 74; + public static final int JBC_astore_0 = 75; + public static final int JBC_astore_1 = 76; + public static final int JBC_astore_2 = 77; + public static final int JBC_astore_3 = 78; + public static final int JBC_iastore = 79; + public static final int JBC_lastore = 80; + public static final int JBC_fastore = 81; + public static final int JBC_dastore = 82; + public static final int JBC_aastore = 83; + public static final int JBC_bastore = 84; + public static final int JBC_castore = 85; + public static final int JBC_sastore = 86; + public static final int JBC_pop = 87; + public static final int JBC_pop2 = 88; + public static final int JBC_dup = 89; + public static final int JBC_dup_x1 = 90; + public static final int JBC_dup_x2 = 91; + public static final int JBC_dup2 = 92; + public static final int JBC_dup2_x1 = 93; + public static final int JBC_dup2_x2 = 94; + public static final int JBC_swap = 95; + public static final int JBC_iadd = 96; + public static final int JBC_ladd = 97; + public static final int JBC_fadd = 98; + public static final int JBC_dadd = 99; + public static final int JBC_isub = 100; + public static final int JBC_lsub = 101; + public static final int JBC_fsub = 102; + public static final int JBC_dsub = 103; + public static final int JBC_imul = 104; + public static final int JBC_lmul = 105; + public static final int JBC_fmul = 106; + public static final int JBC_dmul = 107; + public static final int JBC_idiv = 108; + public static final int JBC_ldiv = 109; + public static final int JBC_fdiv = 110; + public static final int JBC_ddiv = 111; + public static final int JBC_irem = 112; + public static final int JBC_lrem = 113; + public static final int JBC_frem = 114; + public static final int JBC_drem = 115; + public static final int JBC_ineg = 116; + public static final int JBC_lneg = 117; + public static final int JBC_fneg = 118; + public static final int JBC_dneg = 119; + public static final int JBC_ishl = 120; + public static final int JBC_lshl = 121; + public static final int JBC_ishr = 122; + public static final int JBC_lshr = 123; + public static final int JBC_iushr = 124; + public static final int JBC_lushr = 125; + public static final int JBC_iand = 126; + public static final int JBC_land = 127; + public static final int JBC_ior = 128; + public static final int JBC_lor = 129; + public static final int JBC_ixor = 130; + public static final int JBC_lxor = 131; + public static final int JBC_iinc = 132; + public static final int JBC_i2l = 133; + public static final int JBC_i2f = 134; + public static final int JBC_i2d = 135; + public static final int JBC_l2i = 136; + public static final int JBC_l2f = 137; + public static final int JBC_l2d = 138; + public static final int JBC_f2i = 139; + public static final int JBC_f2l = 140; + public static final int JBC_f2d = 141; + public static final int JBC_d2i = 142; + public static final int JBC_d2l = 143; + public static final int JBC_d2f = 144; + public static final int JBC_int2byte = 145; + public static final int JBC_int2char = 146; + public static final int JBC_int2short = 147; + public static final int JBC_lcmp = 148; + public static final int JBC_fcmpl = 149; + public static final int JBC_fcmpg = 150; + public static final int JBC_dcmpl = 151; + public static final int JBC_dcmpg = 152; + public static final int JBC_ifeq = 153; + public static final int JBC_ifne = 154; + public static final int JBC_iflt = 155; + public static final int JBC_ifge = 156; + public static final int JBC_ifgt = 157; + public static final int JBC_ifle = 158; + public static final int JBC_if_icmpeq = 159; + public static final int JBC_if_icmpne = 160; + public static final int JBC_if_icmplt = 161; + public static final int JBC_if_icmpge = 162; + public static final int JBC_if_icmpgt = 163; + public static final int JBC_if_icmple = 164; + public static final int JBC_if_acmpeq = 165; + public static final int JBC_if_acmpne = 166; + public static final int JBC_goto = 167; + public static final int JBC_jsr = 168; + public static final int JBC_ret = 169; + public static final int JBC_tableswitch = 170; + public static final int JBC_lookupswitch = 171; + public static final int JBC_ireturn = 172; + public static final int JBC_lreturn = 173; + public static final int JBC_freturn = 174; + public static final int JBC_dreturn = 175; + public static final int JBC_areturn = 176; + public static final int JBC_return = 177; + public static final int JBC_getstatic = 178; + public static final int JBC_putstatic = 179; + public static final int JBC_getfield = 180; + public static final int JBC_putfield = 181; + public static final int JBC_invokevirtual = 182; + public static final int JBC_invokespecial = 183; + public static final int JBC_invokestatic = 184; + public static final int JBC_invokeinterface = 185; + public static final int JBC_xxxunusedxxx = 186; + public static final int JBC_new = 187; + public static final int JBC_newarray = 188; + public static final int JBC_anewarray = 189; + public static final int JBC_arraylength = 190; + public static final int JBC_athrow = 191; + public static final int JBC_checkcast = 192; + public static final int JBC_instanceof = 193; + public static final int JBC_monitorenter = 194; + public static final int JBC_monitorexit = 195; + public static final int JBC_wide = 196; + public static final int JBC_multianewarray = 197; + public static final int JBC_ifnull = 198; + public static final int JBC_ifnonnull = 199; + public static final int JBC_goto_w = 200; + public static final int JBC_jsr_w = 201; + + public static final int JBC_impdep1 = 254; + public static final int JBC_impdep2 = 255; + + // Length of each instruction introduced by the above bytecodes. + // -1 indicates a variable length instruction. + // -2 indicates an unused instruction. + // + public static final byte JBC_length[] = { 1, // nop + 1, // aconst_null + 1, // iconst_m1 + 1, // iconst_0 + 1, // iconst_1 + 1, // iconst_2 + 1, // iconst_3 + 1, // iconst_4 + 1, // iconst_5 + 1, // lconst_0 + 1, // lconst_1 + 1, // fconst_0 + 1, // fconst_1 + 1, // fconst_2 + 1, // dconst_0 + 1, // dconst_1 + 2, // bipush + 3, // sipush + 2, // ldc + 3, // ldc_w + 3, // ldc2_w + 2, // iload + 2, // lload + 2, // fload + 2, // dload + 2, // aload + 1, // iload_0 + 1, // iload_1 + 1, // iload_2 + 1, // iload_3 + 1, // lload_0 + 1, // lload_1 + 1, // lload_2 + 1, // lload_3 + 1, // fload_0 + 1, // fload_1 + 1, // fload_2 + 1, // fload_3 + 1, // dload_0 + 1, // dload_1 + 1, // dload_2 + 1, // dload_3 + 1, // aload_0 + 1, // aload_1 + 1, // aload_2 + 1, // aload_3 + 1, // iaload + 1, // laload + 1, // faload + 1, // daload + 1, // aaload + 1, // baload + 1, // caload + 1, // saload + 2, // istore + 2, // lstore + 2, // fstore + 2, // dstore + 2, // astore + 1, // istore_0 + 1, // istore_1 + 1, // istore_2 + 1, // istore_3 + 1, // lstore_0 + 1, // lstore_1 + 1, // lstore_2 + 1, // lstore_3 + 1, // fstore_0 + 1, // fstore_1 + 1, // fstore_2 + 1, // fstore_3 + 1, // dstore_0 + 1, // dstore_1 + 1, // dstore_2 + 1, // dstore_3 + 1, // astore_0 + 1, // astore_1 + 1, // astore_2 + 1, // astore_3 + 1, // iastore + 1, // lastore + 1, // fastore + 1, // dastore + 1, // aastore + 1, // bastore + 1, // castore + 1, // sastore + 1, // pop + 1, // pop2 + 1, // dup + 1, // dup_x1 + 1, // dup_x2 + 1, // dup2 + 1, // dup2_x1 + 1, // dup2_x2 + 1, // swap + 1, // iadd + 1, // ladd + 1, // fadd + 1, // dadd + 1, // isub + 1, // lsub + 1, // fsub + 1, // dsub + 1, // imul + 1, // lmul + 1, // fmul + 1, // dmul + 1, // idiv + 1, // ldiv + 1, // fdiv + 1, // ddiv + 1, // irem + 1, // lrem + 1, // frem + 1, // drem + 1, // ineg + 1, // lneg + 1, // fneg + 1, // dneg + 1, // ishl + 1, // lshl + 1, // ishr + 1, // lshr + 1, // iushr + 1, // lushr + 1, // iand + 1, // land + 1, // ior + 1, // lor + 1, // ixor + 1, // lxor + 3, // iinc + 1, // i2l + 1, // i2f + 1, // i2d + 1, // l2i + 1, // l2f + 1, // l2d + 1, // f2i + 1, // f2l + 1, // f2d + 1, // d2i + 1, // d2l + 1, // d2f + 1, // int2byte + 1, // int2char + 1, // int2short + 1, // lcmp + 1, // fcmpl + 1, // fcmpg + 1, // dcmpl + 1, // dcmpg + 3, // ifeq + 3, // ifne + 3, // iflt + 3, // ifge + 3, // ifgt + 3, // ifle + 3, // if_icmpeq + 3, // if_icmpne + 3, // if_icmplt + 3, // if_icmpge + 3, // if_icmpgt + 3, // if_icmple + 3, // if_acmpeq + 3, // if_acmpne + 3, // goto + 3, // jsr + 2, // ret + -1, // tableswitch + -1, // lookupswitch + 1, // ireturn + 1, // lreturn + 1, // freturn + 1, // dreturn + 1, // areturn + 1, // return + 3, // getstatic + 3, // putstatic + 3, // getfield + 3, // putfield + 3, // invokevirtual + 3, // invokenonvirtual + 3, // invokestatic + 5, // invokeinterface + -2, // xxxunusedxxx + 3, // new + 2, // newarray + 3, // anewarray + 1, // arraylength + 1, // athrow + 3, // checkcast + 3, // instanceof + 1, // monitorenter + 1, // monitorexit + -1, // wide + 4, // multianewarray + 3, // ifnull + 3, // ifnonnull + 5, // goto_w + 5, // jsr_w + + }; + + /** + * Bytecode names (for debugging/printing) + */ + public static final String JBC_name[] = + { + "nop", + "aconst_null", + "iconst_m1", + "iconst_0", + "iconst_1", + "iconst_2", + "iconst_3", + "iconst_4", + "iconst_5", + "lconst_0", + "lconst_1", + "fconst_0", + "fconst_1", + "fconst_2", + "dconst_0", + "dconst_1", + "bipush", + "sipush", + "ldc", + "ldc_w", + "ldc2_w", + "iload", + "lload", + "fload", + "dload", + "aload", + "iload_0", + "iload_1", + "iload_2", + "iload_3", + "lload_0", + "lload_1", + "lload_2", + "lload_3", + "fload_0", + "fload_1", + "fload_2", + " fload_3", + " dload_0", + " dload_1", + " dload_2", + " dload_3", + " aload_0", + " aload_1", + " aload_2", + " aload_3", + " iaload", + " laload", + " faload", + " daload", + " aaload", + " baload", + " caload", + " saload", + " istore", + " lstore", + " fstore", + " dstore", + " astore", + " istore_0", + " istore_1", + " istore_2", + " istore_3", + " lstore_0", + " lstore_1", + " lstore_2", + " lstore_3", + " fstore_0", + " fstore_1", + " fstore_2", + " fstore_3", + " dstore_0", + " dstore_1", + " dstore_2", + " dstore_3", + " astore_0", + " astore_1", + " astore_2", + " astore_3", + "iastore", + "lastore", + "fastore", + "dastore", + "aastore", + "bastore", + "castore", + "sastore", + "pop", + "pop2", + "dup", + "dup_x1", + "dup_x2", + "dup2", + "dup2_x1", + "dup2_x2", + "swap", + "iadd", + "ladd", + "fadd", + "dadd", + "isub", + "lsub", + "fsub", + "dsub", + "imul", + "lmul", + "fmul", + "dmul", + "idiv", + "ldiv", + "fdiv", + "ddiv", + "irem", + "lrem", + "frem", + "drem", + "ineg", + "lneg", + "fneg", + "dneg", + "ishl", + "lshl", + "ishr", + "lshr", + "iushr", + "lushr", + "iand", + "land", + "ior", + "lor", + "ixor", + "lxor", + "iinc", + "i2l", + "i2f", + "i2d", + "l2i", + "l2f", + "l2d", + "f2i", + "f2l", + "f2d", + "d2i", + "d2l", + "d2f", + "int2byte", + "int2char", + "int2short", + "lcmp", + "fcmpl", + "fcmpg", + "dcmpl", + "dcmpg", + "ifeq", + "ifne", + "iflt", + "ifge", + "ifgt", + "ifle", + "if_icmpeq", + "if_icmpne", + "if_icmplt", + "if_icmpge", + "if_icmpgt", + "if_icmple", + "if_acmpeq", + "if_acmpne", + "goto", + "jsr", + "ret", + " tableswitch", + " lookupswitch", + "ireturn", + "lreturn", + "freturn", + "dreturn", + "areturn", + "return", + "getstatic", + "putstatic", + "getfield", + "putfield", + "invokevirtual", + "invokenonvirtual", + "invokestatic", + "invokeinterface", + " xxxunusedxxx", + "new", + "newarray", + "anewarray", + "arraylength", + "athrow", + "checkcast", + "instanceof", + "monitorenter", + "monitorexit", + " wide", + "multianewarray", + "ifnull", + "ifnonnull", + "goto_w", + "jsr_w", + }; + +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/CheckCastInstruction.java b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/CheckCastInstruction.java new file mode 100644 index 000000000..a1efc9278 --- /dev/null +++ b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/CheckCastInstruction.java @@ -0,0 +1,73 @@ +/******************************************************************************* + * 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.shrikeBT; + +/** + * This class represents checkcast instructions. + */ +final public class CheckCastInstruction extends Instruction { + private String type; + + protected CheckCastInstruction(String type) { + this.type = type; + this.opcode = OP_checkcast; + } + + public static CheckCastInstruction make(String type) { + return new CheckCastInstruction(type.intern()); + } + + public boolean equals(Object o) { + if (o instanceof CheckCastInstruction) { + CheckCastInstruction i = (CheckCastInstruction) o; + return i.type.equals(type); + } else { + return false; + } + } + + public int hashCode() { + return 131111 + type.hashCode(); + } + + public int getPoppedCount() { + return 1; + } + + /** + * @return the type to which the operand is cast + */ + public String getType() { + return type; + } + + public String getPushedType(String[] types) { + return type; + } + + public byte getPushedWordSize() { + return 1; + } + + public void visit(Visitor v) { + v.visitCheckCast(this); + } + + public String toString() { + return "CheckCast(" + type + ")"; + } + /* (non-Javadoc) + * @see com.ibm.domo.cfg.IInstruction#isPEI() + */ + public boolean isPEI() { + return true; + } +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/ComparisonInstruction.java b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/ComparisonInstruction.java new file mode 100644 index 000000000..385585b67 --- /dev/null +++ b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/ComparisonInstruction.java @@ -0,0 +1,133 @@ +/******************************************************************************* + * 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.shrikeBT; + +/** + * This class represents comparisons between floats, longs and doubles. + */ +final public class ComparisonInstruction extends Instruction { + public enum Operator { + CMP, CMPL, CMPG; + + @Override + public String toString() { + return super.toString().toLowerCase(); + } + } + + protected ComparisonInstruction(short opcode) { + this.opcode = opcode; + } + + private final static ComparisonInstruction preallocatedLCMP = new ComparisonInstruction((short) OP_lcmp); + private final static ComparisonInstruction[] preallocatedFloatingCompares = preallocateFloatingCompares(); + + private static ComparisonInstruction[] preallocateFloatingCompares() { + ComparisonInstruction[] r = new ComparisonInstruction[OP_dcmpg - OP_fcmpl + 1]; + for (short i = OP_fcmpl; i <= OP_dcmpg; i++) { + r[i - OP_fcmpl] = new ComparisonInstruction(i); + } + return r; + } + + public static ComparisonInstruction make(String type, Operator operator) { + int t = Util.getTypeIndex(type); + switch (t) { + case TYPE_long_index: + if (operator != Operator.CMP) { + throw new IllegalArgumentException("Operator " + operator + " is not a valid comparison operator for longs"); + } else { + return preallocatedLCMP; + } + case TYPE_float_index: + case TYPE_double_index: + if (operator == Operator.CMP) { + throw new IllegalArgumentException("Operator " + operator + " is not a valid comparison operator for floating point values"); + } else { + return preallocatedFloatingCompares[(operator.ordinal() - Operator.CMPL.ordinal()) + (t - TYPE_float_index) * 2]; + } + default: + throw new IllegalArgumentException("Type " + type + " cannot be compared"); + } + } + + public boolean equals(Object o) { + if (o instanceof ComparisonInstruction) { + ComparisonInstruction i = (ComparisonInstruction) o; + return i.opcode == opcode; + } else { + return false; + } + } + + /** + * @return OPR_cmp (for long), OPR_cmpl, or OPR_cmpg (for float and double) + */ + public Operator getOperator() { + switch (opcode) { + case OP_lcmp: + return Operator.CMP; + case OP_fcmpl: + case OP_dcmpl: + return Operator.CMPL; + case OP_dcmpg: + case OP_fcmpg: + return Operator.CMPG; + default: + throw new Error("Unknown opcode"); + } + } + + public String getType() { + switch (opcode) { + case OP_lcmp: + return TYPE_long; + case OP_fcmpg: + case OP_fcmpl: + return TYPE_float; + case OP_dcmpl: + case OP_dcmpg: + return TYPE_double; + default: + throw new Error("Unknown opcode"); + } + } + + public int hashCode() { + return opcode + 1391901; + } + + public int getPoppedCount() { + return 2; + } + + public String getPushedType(String[] types) { + return Constants.TYPE_boolean; + } + + public byte getPushedWordSize() { + return 1; + } + + public void visit(Visitor v) { + v.visitComparison(this); + } + + public String toString() { + return "Comparison(" + getType() + "," + getOperator() + ")"; + } + /* (non-Javadoc) + * @see com.ibm.domo.cfg.IInstruction#isPEI() + */ + public boolean isPEI() { + return false; + } +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/Compiler.java b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/Compiler.java new file mode 100644 index 000000000..863f03207 --- /dev/null +++ b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/Compiler.java @@ -0,0 +1,1799 @@ +/******************************************************************************* + * 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.shrikeBT; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.BitSet; +import java.util.Iterator; + +import com.ibm.wala.shrikeBT.BinaryOpInstruction.Operator; +import com.ibm.wala.shrikeBT.analysis.ClassHierarchyProvider; +import com.ibm.wala.shrikeBT.analysis.Verifier; + +/** + * This class generates Java bytecode from ShrikeBT Instructions. + * + * If there are too many instructions to fit into 64K bytecodes, then we break + * the method up, generating auxiliary methods called by the main method. + * + * This class is abstract; there are subclasses for specific class file access + * toolkits. These toolkits are responsible for providing ways to allocate + * constant pool entries. + */ +public abstract class Compiler implements Constants { + // input + private boolean isStatic; + private String classType; + private String signature; + private Instruction[] instructions; + private ExceptionHandler[][] handlers; + private int[] instructionsToBytecodes; + + private static final int[] noRawHandlers = new int[0]; + + private ClassHierarchyProvider hierarchy; + private ConstantPoolReader presetConstants; + + // working + private int[] instructionsToOffsets; + private BitSet branchTargets; + private byte[][] stackWords; + private byte[] code; + + // working on breaking up overlarge methods + private int allocatedLocals; + private BitSet[] liveLocals; + private int[][] backEdges; + private String[][] localTypes; + private String[][] stackTypes; + + // output + private int maxLocals; + private int maxStack; + private Output mainMethod; + private ArrayList auxMethods; + + /** + * Initialize a Compiler for the given method data. + * + * @param isStatic + * true iff the method is static + * @param classType + * the JVM type of the class the method belongs to + * @param signature + * the JVM signature of the method + * @param instructions + * the ShrikeBT instructions + * @param handlers + * the ShrikeBT exception handlers + * @param instructionsToBytecodes + * the map from instructions to original bytecode offsets + */ + public Compiler(boolean isStatic, String classType, String signature, Instruction[] instructions, ExceptionHandler[][] handlers, + int[] instructionsToBytecodes) { + if (instructions.length != handlers.length) { + throw new IllegalArgumentException("Instructions/handlers length mismatch"); + } + if (instructions.length != instructionsToBytecodes.length) { + throw new IllegalArgumentException("Instructions/handlers length mismatch"); + } + + this.isStatic = isStatic; + this.classType = classType; + this.signature = signature; + this.instructions = instructions; + this.handlers = handlers; + this.instructionsToBytecodes = instructionsToBytecodes; + } + + /** + * Extract the data for the method to be compiled from the MethodData + * container. + */ + public Compiler(MethodData info) { + this(info.getIsStatic(), info.getClassType(), info.getSignature(), info.getInstructions(), info.getHandlers(), info + .getInstructionsToBytecodes()); + } + + /** + * @return the JVM type for the class this method belongs to + */ + final public String getClassType() { + return classType; + } + + /** + * Notify the compiler that the constants appearing in the ConstantPoolReader + * cp will appear in the final class file. + * + * Instructions which were extracted from a class file with the same + * ConstantPoolReader can be written back much more efficiently if the same + * constant pool indices are valid in the new class file. + */ + final public void setPresetConstants(ConstantPoolReader cp) { + presetConstants = cp; + } + + final public void setClassHierarchy(ClassHierarchyProvider h) { + this.hierarchy = h; + } + + protected abstract int allocateConstantPoolInteger(int v); + + protected abstract int allocateConstantPoolFloat(float v); + + protected abstract int allocateConstantPoolLong(long v); + + protected abstract int allocateConstantPoolDouble(double v); + + protected abstract int allocateConstantPoolString(String v); + + protected abstract int allocateConstantPoolClassType(String c); + + protected abstract int allocateConstantPoolField(String c, String name, String type); + + protected abstract int allocateConstantPoolMethod(String c, String name, String sig); + + protected abstract int allocateConstantPoolInterfaceMethod(String c, String name, String sig); + + protected abstract String createHelperMethod(boolean isStatic, String sig); + + private void collectInstructionInfo() { + final BitSet s = new BitSet(instructions.length); + final BitSet localsUsed = new BitSet(32); + final BitSet localsWide = new BitSet(32); + + Instruction.Visitor visitor = new Instruction.Visitor() { + private void visitTargets(Instruction instr) { + int[] ts = instr.getBranchTargets(); + for (int k = 0; k < ts.length; k++) { + s.set(ts[k]); + } + } + + public void visitGoto(GotoInstruction instruction) { + visitTargets(instruction); + } + + public void visitLocalStore(StoreInstruction instruction) { + localsUsed.set(instruction.getVarIndex()); + String t = instruction.getType(); + if (t.equals(TYPE_long) || t.equals(TYPE_double)) { + localsWide.set(instruction.getVarIndex()); + } + } + + public void visitConditionalBranch(ConditionalBranchInstruction instruction) { + visitTargets(instruction); + } + + public void visitSwitch(SwitchInstruction instruction) { + visitTargets(instruction); + } + }; + + for (int i = 0; i < instructions.length; i++) { + instructions[i].visit(visitor); + } + + String[] paramTypes = Util.getParamsTypes(isStatic ? null : TYPE_Object, signature); + int index = 0; + for (int i = 0; i < paramTypes.length; i++) { + String t = paramTypes[i]; + localsUsed.set(index); + if (t.equals(TYPE_long) || t.equals(TYPE_double)) { + localsWide.set(index); + index += 2; + } else { + index++; + } + } + + ExceptionHandler[] lastHS = null; + for (int i = 0; i < handlers.length; i++) { + ExceptionHandler[] hs = handlers[i]; + if (hs != lastHS) { + for (int j = 0; j < hs.length; j++) { + s.set(hs[j].handler); + } + lastHS = hs; + } + } + + this.branchTargets = s; + + int maxUsed = localsUsed.length(); + if (maxUsed > 0 && localsWide.get(maxUsed - 1)) { + maxUsed++; + } + this.maxLocals = maxUsed; + } + + private void writeInt(int offset, int v) { + code[offset] = (byte) (v >> 24); + code[offset + 1] = (byte) (v >> 16); + code[offset + 2] = (byte) (v >> 8); + code[offset + 3] = (byte) v; + } + + private void writeShort(int offset, int v) { + code[offset] = (byte) (v >> 8); + code[offset + 1] = (byte) v; + } + + private void writeByte(int offset, int v) { + code[offset] = (byte) v; + } + + private boolean inBasicBlock(int i, int n) { + if (i + n - 1 >= instructions.length) { + return false; + } + + for (int j = i + 1; j < i + n; j++) { + if (branchTargets.get(j)) { + return false; + } + + if (!Arrays.equals(handlers[j], handlers[i])) { + return false; + } + + if (instructionsToBytecodes[j] != instructionsToBytecodes[i]) { + return false; + } + } + + return true; + } + + private void checkStackWordSize(byte[] stackWords, int stackLen) { + if (stackLen * 2 > maxStack) { + int words = 0; + for (int i = 0; i < stackLen; i++) { + words += stackWords[i]; + } + if (words > maxStack) { + maxStack = words; + } + } + } + +// private static int getStackDelta(Instruction instr) { +// if (instr instanceof DupInstruction) { +// return ((DupInstruction) instr).getSize(); +// } else { +// return (instr.getPushedWordSize() > 0 ? 1 : 0) - instr.getPoppedCount(); +// } +// } + + private void computeStackWordsAt(int i, int stackLen, byte[] stackWords, boolean[] visited) { + while (!visited[i]) { + Instruction instr = instructions[i]; + + if (i > 0 && !instructions[i - 1].isFallThrough()) { + byte[] newWords = new byte[stackLen]; + System.arraycopy(stackWords, 0, newWords, 0, stackLen); + this.stackWords[i] = newWords; + } + + visited[i] = true; + + if (stackLen < instr.getPoppedCount()) { + throw new IllegalArgumentException("Stack underflow in intermediate code, at offset " + i); + } + + if (instr instanceof DupInstruction) { + DupInstruction d = (DupInstruction) instr; + int size = d.getSize(); + int delta = d.getDelta(); + + System.arraycopy(stackWords, stackLen - size - delta, stackWords, stackLen - delta, delta + size); + System.arraycopy(stackWords, stackLen, stackWords, stackLen - size - delta, size); + stackLen += size; + checkStackWordSize(stackWords, stackLen); + } else if (instr instanceof SwapInstruction) { + // we may have to emulate this using a dup[2]_x[1,2] + // followed by a pop[2]. So update the maxStack to account for the + // temporarily larger stack size + int words = stackWords[stackLen - 1]; + for (int j = 0; j < stackLen; j++) { + words += stackWords[j]; + } + if (words > maxStack) { + maxStack = words; + } + + byte b = stackWords[stackLen - 2]; + stackWords[stackLen - 2] = stackWords[stackLen - 1]; + stackWords[stackLen - 1] = b; + } else { + stackLen -= instr.getPoppedCount(); + + byte w = instr.getPushedWordSize(); + if (w > 0) { + stackWords[stackLen] = w; + stackLen++; + checkStackWordSize(stackWords, stackLen); + } + } + + int[] bt = instr.getBranchTargets(); + for (int j = 0; j < bt.length; j++) { + int t = bt[j]; + if (t < 0 || t >= visited.length) { + throw new IllegalArgumentException("Branch target at offset " + i + " is out of bounds: " + t + " (max " + visited.length + + ")"); + } + if (!visited[t]) { + computeStackWordsAt(bt[j], stackLen, (byte[]) stackWords.clone(), visited); + } + } + + ExceptionHandler[] hs = handlers[i]; + for (int j = 0; j < hs.length; j++) { + int t = hs[j].handler; + if (!visited[t]) { + byte[] newWords = (byte[]) stackWords.clone(); + newWords[0] = 1; + computeStackWordsAt(t, 1, newWords, visited); + } + } + + if (!instr.isFallThrough()) { + return; + } + + i++; + } + } + + private void computeStackWords() { + stackWords = new byte[instructions.length][]; + maxStack = 0; + + computeStackWordsAt(0, 0, new byte[instructions.length * 2], new boolean[instructions.length]); + } + + abstract class Patch { + int instrStart; + int instrOffset; + int targetLabel; + + Patch(int instrStart, int instrOffset, int targetLabel) { + this.instrStart = instrStart; + this.instrOffset = instrOffset; + this.targetLabel = targetLabel; + } + + abstract boolean apply(); + } + + class ShortPatch extends Patch { + ShortPatch(int instrStart, int instrOffset, int targetLabel) { + super(instrStart, instrOffset, targetLabel); + } + + boolean apply() { + int delta = instructionsToOffsets[targetLabel] - instrStart; + if ((short) delta == delta) { + writeShort(instrOffset, delta); + return true; + } else { + return false; + } + } + } + + class IntPatch extends Patch { + IntPatch(int instrStart, int instrOffset, int targetLabel) { + super(instrStart, instrOffset, targetLabel); + } + + boolean apply() { + writeInt(instrOffset, instructionsToOffsets[targetLabel] - instrStart); + return true; + } + } + + private void insertBranchOffsetInt(ArrayList patches, int instrStart, int instrOffset, int targetLabel) { + if (instructionsToOffsets[targetLabel] > 0 || targetLabel == 0) { + writeInt(instrOffset, instructionsToOffsets[targetLabel] - instrStart); + } else { + patches.add(new IntPatch(instrStart, instrOffset, targetLabel)); + } + } + + private boolean applyPatches(ArrayList patches) { + for (Iterator i = patches.iterator(); i.hasNext();) { + Patch p = i.next(); + if (!p.apply()) { + return false; + } + } + return true; + } + + private static byte[] cachedBuf; + + private static synchronized byte[] makeCodeBuf() { + if (cachedBuf != null) { + byte[] result = cachedBuf; + cachedBuf = null; + return result; + } else { + return new byte[65535]; + } + } + + private static synchronized void releaseCodeBuf(byte[] buf) { + cachedBuf = buf; + } + + private boolean outputInstructions(int startInstruction, int endInstruction, int startOffset, boolean farBranches, + byte[] initialStack) { + instructionsToOffsets = new int[instructions.length]; + code = makeCodeBuf(); + + ArrayList patches = new ArrayList(); + + int curOffset = startOffset; + final int[] curOffsetRef = new int[1]; + int stackLen = initialStack == null ? 0 : initialStack.length; + final int[] stackLenRef = new int[1]; + final byte[] stackWords = new byte[maxStack]; + if (stackLen > 0) { + System.arraycopy(initialStack, 0, stackWords, 0, stackLen); + } + final int[] instrRef = new int[1]; + + Instruction.Visitor noOpcodeHandler = new Instruction.Visitor() { + public void visitPop(PopInstruction instruction) { + int count = instruction.getPoppedCount(); + int offset = curOffsetRef[0]; + int stackLen = stackLenRef[0]; + + while (count > 0) { + code[offset] = (byte) (stackWords[stackLen - 1] == 1 ? OP_pop : OP_pop2); + count--; + stackLen--; + offset++; + } + + curOffsetRef[0] = offset; + } + + public void visitDup(DupInstruction instruction) { + int size = instruction.getSize(); + int delta = instruction.getDelta(); + int offset = curOffsetRef[0]; + int stackLen = stackLenRef[0]; + + int sizeWords = stackWords[stackLen - 1]; + if (size == 2) { + sizeWords += stackWords[stackLen - 2]; + } + int deltaWords = delta == 0 ? 0 : stackWords[stackLen - 1 - size]; + if (delta == 2) { + deltaWords += stackWords[stackLen - 1 - size - 1]; + } + if (sizeWords > 2 || deltaWords > 2) { + throw new IllegalArgumentException("Invalid dup size"); + } + + code[offset] = (byte) (OP_dup + (3 * (sizeWords - 1)) + deltaWords); + offset++; + curOffsetRef[0] = offset; + } + + public void visitSwap(SwapInstruction instruction) { + int offset = curOffsetRef[0]; + int stackLen = stackLenRef[0]; + int topSize = stackWords[stackLen - 1]; + int nextSize = stackWords[stackLen - 2]; + + if (topSize == 1 && nextSize == 1) { + code[offset] = (byte) OP_swap; + offset++; + } else { + code[offset] = (byte) (OP_dup + (3 * (topSize - 1)) + nextSize); + code[offset + 1] = (byte) (topSize == 1 ? OP_pop : OP_pop2); + offset += 2; + } + + curOffsetRef[0] = offset; + } + }; + + for (int i = startInstruction; i < endInstruction; i++) { + Instruction instr = instructions[i]; + int opcode = instr.getOpcode(); + int startI = i; + + instructionsToOffsets[i] = curOffset; + + if (opcode != -1) { + boolean fallToConditional = false; + + code[curOffset] = (byte) opcode; + curOffset++; + + switch (opcode) { + case OP_iconst_0: + if (inBasicBlock(i, 2) && instructions[i + 1] instanceof ConditionalBranchInstruction) { + ConditionalBranchInstruction cbr = (ConditionalBranchInstruction) instructions[i + 1]; + if (cbr.getType().equals(TYPE_int)) { + code[curOffset - 1] = (byte) (cbr.getOperator().ordinal() + OP_ifeq); + fallToConditional = true; + i++; + instr = instructions[i]; + } + } + if (!fallToConditional) { + break; + } + case OP_aconst_null: + if (!fallToConditional && inBasicBlock(i, 2) && instructions[i + 1] instanceof ConditionalBranchInstruction) { + ConditionalBranchInstruction cbr = (ConditionalBranchInstruction) instructions[i + 1]; + if (cbr.getType().equals(TYPE_Object)) { + code[curOffset - 1] = (byte) (cbr.getOperator().ordinal() + OP_ifnull); + fallToConditional = true; + i++; + instr = instructions[i]; + } + } + if (!fallToConditional) { + break; + } + //by Xiangyu + case OP_ifeq: + case OP_ifge: + case OP_ifgt: + case OP_ifle: + case OP_iflt: + case OP_ifne: { + int targetI = instr.getBranchTargets()[0]; + boolean invert = false; + int iStart = curOffset - 1; + + if (inBasicBlock(i, 2) && instr.getBranchTargets()[0] == i + 2 && instructions[i + 1] instanceof GotoInstruction) { + invert = true; + targetI = instructions[i + 1].getBranchTargets()[0]; + i++; + } + + if (targetI <= i) { + int delta = instructionsToOffsets[targetI] - iStart; + if ((short) delta != delta) { + // emit "if_!XX TMP; goto_w L; TMP:" + invert = !invert; + writeShort(curOffset, 8); + code[curOffset + 2] = (byte) OP_goto_w; + writeInt(curOffset + 3, delta - 3); + curOffset += 7; + } else { + writeShort(curOffset, (short) delta); + curOffset += 2; + } + } else { + Patch p; + if (farBranches) { + // emit "if_!XX TMP; goto_w L; TMP:" + invert = !invert; + writeShort(curOffset, 8); + code[curOffset + 2] = (byte) OP_goto_w; + p = new IntPatch(curOffset + 2, curOffset + 3, targetI); + curOffset += 7; + } else { + p = new ShortPatch(iStart, curOffset, targetI); + curOffset += 2; + } + patches.add(p); + } + + if (invert) { + code[iStart] = (byte) (((code[iStart] - OP_ifeq) ^ 1) + OP_ifeq); + } + break; + } + //by Xiangyu + + case OP_if_icmpeq: + case OP_if_icmpge: + case OP_if_icmpgt: + case OP_if_icmple: + case OP_if_icmplt: + case OP_if_icmpne: + case OP_if_acmpeq: + case OP_if_acmpne: { + int targetI = instr.getBranchTargets()[0]; + boolean invert = false; + int iStart = curOffset - 1; + + if (inBasicBlock(i, 2) && instr.getBranchTargets()[0] == i + 2 && instructions[i + 1] instanceof GotoInstruction) { + invert = true; + targetI = instructions[i + 1].getBranchTargets()[0]; + i++; + } + + if (targetI <= i) { + int delta = instructionsToOffsets[targetI] - iStart; + if ((short) delta != delta) { + // emit "if_!XX TMP; goto_w L; TMP:" + invert = !invert; + writeShort(curOffset, 8); + code[curOffset + 2] = (byte) OP_goto_w; + writeInt(curOffset + 3, delta - 3); + curOffset += 7; + } else { + writeShort(curOffset, (short) delta); + curOffset += 2; + } + } else { + Patch p; + if (farBranches) { + // emit "if_!XX TMP; goto_w L; TMP:" + invert = !invert; + writeShort(curOffset, 8); + code[curOffset + 2] = (byte) OP_goto_w; + p = new IntPatch(curOffset + 2, curOffset + 3, targetI); + curOffset += 7; + } else { + p = new ShortPatch(iStart, curOffset, targetI); + curOffset += 2; + } + patches.add(p); + } + + if (invert) { + code[iStart] = (byte) (((code[iStart] - OP_if_icmpeq) ^ 1) + OP_if_icmpeq); + } + break; + } + case OP_bipush: + writeByte(curOffset, ((ConstantInstruction.ConstInt) instr).getIntValue()); + curOffset++; + break; + case OP_sipush: + writeShort(curOffset, ((ConstantInstruction.ConstInt) instr).getIntValue()); + curOffset += 2; + break; + case OP_ldc_w: { + int cpIndex; + ConstantInstruction ci = (ConstantInstruction) instr; + if (presetConstants != null && ci.getLazyConstantPool() == presetConstants) { + cpIndex = ci.getCPIndex(); + } else { + String t = instr.getPushedType(null); + if (t.equals(TYPE_int)) { + cpIndex = allocateConstantPoolInteger(((ConstantInstruction.ConstInt) instr).getIntValue()); + } else if (t.equals(TYPE_String)) { + cpIndex = allocateConstantPoolString((String) ((ConstantInstruction.ConstString) instr).getValue()); + } else { + cpIndex = allocateConstantPoolFloat(((ConstantInstruction.ConstFloat) instr).getFloatValue()); + } + } + + if (cpIndex < 256) { + code[curOffset - 1] = (byte) OP_ldc; + code[curOffset] = (byte) cpIndex; + curOffset++; + } else { + writeShort(curOffset, cpIndex); + curOffset += 2; + } + break; + } + case OP_ldc2_w: { + int cpIndex; + ConstantInstruction ci = (ConstantInstruction) instr; + if (presetConstants != null && ci.getLazyConstantPool() == presetConstants) { + cpIndex = ci.getCPIndex(); + } else { + String t = instr.getPushedType(null); + if (t.equals(TYPE_long)) { + cpIndex = allocateConstantPoolLong(((ConstantInstruction.ConstLong) instr).getLongValue()); + } else { + cpIndex = allocateConstantPoolDouble(((ConstantInstruction.ConstDouble) instr).getDoubleValue()); + } + } + + writeShort(curOffset, cpIndex); + curOffset += 2; + break; + } + case OP_iload_0: + case OP_iload_1: + case OP_iload_2: + case OP_iload_3: + case OP_iload: { + if (inBasicBlock(i, 4)) { + // try to generate an OP_iinc + if (instructions[i + 1] instanceof ConstantInstruction.ConstInt && instructions[i + 2] instanceof BinaryOpInstruction + && instructions[i + 3] instanceof StoreInstruction) { + LoadInstruction i0 = (LoadInstruction) instr; + ConstantInstruction.ConstInt i1 = (ConstantInstruction.ConstInt) instructions[i + 1]; + BinaryOpInstruction i2 = (BinaryOpInstruction) instructions[i + 2]; + StoreInstruction i3 = (StoreInstruction) instructions[i + 3]; + + int c = i1.getIntValue(); + int v = i0.getVarIndex(); + BinaryOpInstruction.Operator op = i2.getOperator(); + if ((short) c == c && i3.getVarIndex() == v && (op == Operator.ADD || op == Operator.SUB) && i2.getType().equals(TYPE_int) + && i3.getType().equals(TYPE_int)) { + if (v < 256 && (byte) c == c) { + code[curOffset - 1] = (byte) OP_iinc; + writeByte(curOffset, v); + writeByte(curOffset + 1, c); + curOffset += 2; + } else { + code[curOffset - 1] = (byte) OP_wide; + code[curOffset] = (byte) OP_iinc; + writeShort(curOffset + 1, v); + writeShort(curOffset + 3, c); + curOffset += 5; + } + instructionsToOffsets[i + 1] = -1; + instructionsToOffsets[i + 2] = -1; + instructionsToOffsets[i + 3] = -1; + i += 3; + break; + } + } + } + if (opcode != OP_iload) { + break; + } + } + case OP_lload: + case OP_fload: + case OP_dload: + case OP_aload: { + int v = ((LoadInstruction) instr).getVarIndex(); + + if (v < 256) { + writeByte(curOffset, v); + curOffset++; + } else { + code[curOffset - 1] = (byte) OP_wide; + code[curOffset] = (byte) opcode; + writeShort(curOffset + 1, v); + curOffset += 3; + } + break; + } + case OP_istore: + case OP_lstore: + case OP_fstore: + case OP_dstore: + case OP_astore: { + int v = ((StoreInstruction) instr).getVarIndex(); + + if (v < 256) { + writeByte(curOffset, v); + curOffset++; + } else { + code[curOffset - 1] = (byte) OP_wide; + code[curOffset] = (byte) opcode; + writeShort(curOffset + 1, v); + curOffset += 3; + } + break; + } + case OP_goto: { + int targetI = instr.getBranchTargets()[0]; + if (targetI <= i) { + int delta = instructionsToOffsets[targetI] - (curOffset - 1); + if ((short) delta != delta) { + code[curOffset - 1] = (byte) OP_goto_w; + writeInt(curOffset, delta); + curOffset += 4; + } else { + writeShort(curOffset, (short) delta); + curOffset += 2; + } + } else if (targetI == i + 1) { + // ignore noop gotos + curOffset--; + } else { + Patch p; + if (farBranches) { + code[curOffset - 1] = (byte) OP_goto_w; + p = new IntPatch(curOffset - 1, curOffset, instr.getBranchTargets()[0]); + curOffset += 4; + } else { + p = new ShortPatch(curOffset - 1, curOffset, instr.getBranchTargets()[0]); + curOffset += 2; + } + patches.add(p); + } + break; + } + case OP_lookupswitch: { + int start = curOffset - 1; + SwitchInstruction sw = (SwitchInstruction) instr; + int[] casesAndLabels = sw.getCasesAndLabels(); + + while ((curOffset & 3) != 0) { + writeByte(curOffset, 0); + curOffset++; + } + + if (curOffset + 4 * casesAndLabels.length + 8 > code.length) { + return false; + } + insertBranchOffsetInt(patches, start, curOffset, sw.getDefaultLabel()); + writeInt(curOffset + 4, casesAndLabels.length / 2); + curOffset += 8; + for (int j = 0; j < casesAndLabels.length; j += 2) { + writeInt(curOffset, casesAndLabels[j]); + insertBranchOffsetInt(patches, start, curOffset + 4, casesAndLabels[j + 1]); + curOffset += 8; + } + break; + } + case OP_tableswitch: { + int start = curOffset - 1; + SwitchInstruction sw = (SwitchInstruction) instr; + int[] casesAndLabels = sw.getCasesAndLabels(); + + while ((curOffset & 3) != 0) { + writeByte(curOffset, 0); + curOffset++; + } + if (curOffset + 2 * casesAndLabels.length + 12 > code.length) { + return false; + } + insertBranchOffsetInt(patches, start, curOffset, sw.getDefaultLabel()); + writeInt(curOffset + 4, casesAndLabels[0]); + writeInt(curOffset + 8, casesAndLabels[casesAndLabels.length - 2]); + curOffset += 12; + for (int j = 0; j < casesAndLabels.length; j += 2) { + insertBranchOffsetInt(patches, start, curOffset, casesAndLabels[j + 1]); + curOffset += 4; + } + break; + } + case OP_getfield: + case OP_getstatic: { + GetInstruction g = (GetInstruction) instr; + int cpIndex; + + if (presetConstants != null && presetConstants == g.getLazyConstantPool()) { + cpIndex = ((GetInstruction.Lazy) g).getCPIndex(); + } else { + cpIndex = allocateConstantPoolField(g.getClassType(), g.getFieldName(), g.getFieldType()); + } + writeShort(curOffset, cpIndex); + curOffset += 2; + break; + } + case OP_putfield: + case OP_putstatic: { + PutInstruction p = (PutInstruction) instr; + int cpIndex; + + if (presetConstants != null && presetConstants == p.getLazyConstantPool()) { + cpIndex = ((PutInstruction.Lazy) p).getCPIndex(); + } else { + cpIndex = allocateConstantPoolField(p.getClassType(), p.getFieldName(), p.getFieldType()); + } + writeShort(curOffset, cpIndex); + curOffset += 2; + break; + } + case OP_invokespecial: + case OP_invokestatic: + case OP_invokevirtual: { + InvokeInstruction inv = (InvokeInstruction) instr; + int cpIndex; + + if (presetConstants != null && presetConstants == inv.getLazyConstantPool()) { + cpIndex = ((InvokeInstruction.Lazy) inv).getCPIndex(); + } else { + cpIndex = allocateConstantPoolMethod(inv.getClassType(), inv.getMethodName(), inv.getMethodSignature()); + } + writeShort(curOffset, cpIndex); + curOffset += 2; + break; + } + case OP_invokeinterface: { + InvokeInstruction inv = (InvokeInstruction) instr; + String sig = inv.getMethodSignature(); + int cpIndex; + + if (presetConstants != null && presetConstants == inv.getLazyConstantPool()) { + cpIndex = ((InvokeInstruction.Lazy) inv).getCPIndex(); + } else { + cpIndex = allocateConstantPoolInterfaceMethod(inv.getClassType(), inv.getMethodName(), sig); + } + writeShort(curOffset, cpIndex); + code[curOffset + 2] = (byte) (Util.getParamsWordSize(sig) + 1); + code[curOffset + 3] = 0; + curOffset += 4; + break; + } + case OP_new: + writeShort(curOffset, allocateConstantPoolClassType(((NewInstruction) instr).getType())); + curOffset += 2; + break; + case OP_newarray: + code[curOffset] = indexedTypes_T[Util.getTypeIndex(((NewInstruction) instr).getType().substring(1))]; + curOffset++; + break; + case OP_anewarray: + writeShort(curOffset, allocateConstantPoolClassType(((NewInstruction) instr).getType().substring(1))); + curOffset += 2; + break; + case OP_multianewarray: { + NewInstruction n = (NewInstruction) instr; + writeShort(curOffset, allocateConstantPoolClassType(n.getType())); + code[curOffset + 2] = (byte) n.getArrayBoundsCount(); + curOffset += 3; + break; + } + case OP_checkcast: + writeShort(curOffset, allocateConstantPoolClassType(((CheckCastInstruction) instr).getType())); + curOffset += 2; + break; + case OP_instanceof: + writeShort(curOffset, allocateConstantPoolClassType(((InstanceofInstruction) instr).getType())); + curOffset += 2; + break; + } + } else { + stackLenRef[0] = stackLen; + curOffsetRef[0] = curOffset; + instrRef[0] = i; + instr.visit(noOpcodeHandler); + curOffset = curOffsetRef[0]; + i = instrRef[0]; + } + + boolean haveStack = true; + + while (startI <= i) { + instr = instructions[startI]; + if (instr.isFallThrough() && haveStack) { + if (stackLen < instr.getPoppedCount()) { + throw new IllegalArgumentException("Stack underflow in intermediate code, at offset " + startI); + } + + if (instr instanceof DupInstruction) { + DupInstruction d = (DupInstruction) instr; + int size = d.getSize(); + int delta = d.getDelta(); + + System.arraycopy(stackWords, stackLen - size - delta, stackWords, stackLen - delta, delta + size); + System.arraycopy(stackWords, stackLen, stackWords, stackLen - size - delta, size); + stackLen += size; + } else if (instr instanceof SwapInstruction) { + byte b = stackWords[stackLen - 1]; + stackWords[stackLen - 1] = stackWords[stackLen - 2]; + stackWords[stackLen - 2] = b; + } else { + stackLen -= instr.getPoppedCount(); + + byte w = instr.getPushedWordSize(); + if (w > 0) { + stackWords[stackLen] = w; + stackLen++; + } + } + } else { + // No stack, or the instruction doesn't fall through + // try to grab the stack state at the start of the next instruction + if (startI + 1 < endInstruction) { + byte[] s = this.stackWords[startI + 1]; + // if the next instruction doesn't have stack info (it's not + // reachable), then just ignore it and remember that we don't have + // stack info + if (s == null) { + haveStack = false; + } else { + stackLen = s.length; + System.arraycopy(s, 0, stackWords, 0, stackLen); + } + } + } + + startI++; + } + + if (curOffset > code.length - 8) { + return false; + } + + if (!haveStack) { + // skip forward through the unreachable instructions until we find + // an instruction for which we know the stack state + while (i + 1 < endInstruction) { + byte[] s = this.stackWords[i + 1]; + if (s != null) { + stackLen = s.length; + System.arraycopy(s, 0, stackWords, 0, stackLen); + break; + } + i++; + } + } + } + + if (applyPatches(patches)) { + byte[] newCode = new byte[curOffset]; + System.arraycopy(code, 0, newCode, 0, curOffset); + releaseCodeBuf(code); + code = newCode; + } else { + if (farBranches) { + throw new Error("Failed to apply patches even with farBranches on"); + } else { + return outputInstructions(startInstruction, endInstruction, startOffset, true, initialStack); + } + } + + return true; + } + + private int[] buildRawHandlers(int start, int end) { + int[] handlerCounts = new int[end - start]; + int maxCount = 0; + + for (int i = start; i < end; i++) { + int len = handlers[i].length; + handlerCounts[i - start] = len; + if (len > maxCount) { + maxCount = len; + } + } + + if (maxCount == 0) { + return noRawHandlers; + } else { + ArrayList rawHandlerList = new ArrayList(); + + for (int i = maxCount; i > 0; i--) { + for (int j = start; j < end; j++) { + if (handlerCounts[j - start] == i) { + int first = j; + ExceptionHandler h = handlers[j][handlers[j].length - i]; + + do { + handlerCounts[j - start]--; + j++; + } while (j < end && handlerCounts[j - start] == i && handlers[j][handlers[j].length - i].equals(h)); + + if (h.handler >= start && h.handler < end) { + rawHandlerList.add(new int[] { instructionsToOffsets[first], j < end ? instructionsToOffsets[j] : code.length, + instructionsToOffsets[h.handler], h.catchClass == null ? 0 : allocateConstantPoolClassType(h.catchClass) }); + } + + j--; + } + } + } + + int[] rawHandlers = new int[4 * rawHandlerList.size()]; + int count = 0; + for (Iterator iter = rawHandlerList.iterator(); iter.hasNext();) { + int[] element = iter.next(); + System.arraycopy(element, 0, rawHandlers, count, 4); + count += 4; + } + return rawHandlers; + } + } + + private int[] buildBytecodeMap(int start, int end) { + int[] r = new int[code.length]; + + for (int i = 0; i < r.length; i++) { + r[i] = -1; + } + + for (int i = start; i < end; i++) { + int off = instructionsToOffsets[i]; + if (off >= 0) { + r[off] = instructionsToBytecodes[i]; + } + } + + return r; + } + + static class HelperPatch { + int start; + int length; + Instruction[] code; + ExceptionHandler[] handlers; + + HelperPatch(int start, int length, Instruction[] code, ExceptionHandler[] handlers) { + this.start = start; + this.length = length; + this.code = code; + this.handlers = handlers; + } + } + + private void addBackEdge(int from, int to) { + int[] oldEdges = backEdges[from]; + if (oldEdges == null) { + backEdges[from] = new int[] { to }; + } else if (oldEdges[oldEdges.length - 1] < 0) { + int left = 1; + int right = oldEdges.length - 1; + while (true) { + if (right - left < 2) { + if (oldEdges[left] < 0) { + break; + } else { + if (oldEdges[right] >= 0) + throw new Error("Failed binary search"); + left = right; + break; + } + } else { + int mid = (left + right) / 2; + if (oldEdges[mid] < 0) { + right = mid; + } else { + left = mid + 1; + } + } + } + oldEdges[left] = to; + } else { + int[] newEdges = new int[oldEdges.length * 2]; + System.arraycopy(oldEdges, 0, newEdges, 0, oldEdges.length); + newEdges[oldEdges.length] = to; + for (int i = oldEdges.length + 1; i < newEdges.length; i++) { + newEdges[i] = -1; + } + backEdges[from] = newEdges; + } + } + + private void addLiveVar(int instruction, int index) { + while (true) { + if (liveLocals[instruction].get(index)) { + break; + } + + Instruction instr = instructions[instruction]; + if (instr instanceof StoreInstruction && ((StoreInstruction) instr).getVarIndex() == index) { + break; + } + + liveLocals[instruction].set(index); + int[] back = backEdges[instruction]; + if (back != null) { + for (int i = 0; i < back.length; i++) { + addLiveVar(back[i], index); + } + } + + if (instruction > 0 && instructions[instruction - 1].isFallThrough()) { + instruction--; + } else { + break; + } + } + } + + private void makeLiveLocals() { + liveLocals = new BitSet[instructions.length]; + backEdges = new int[instructions.length][]; + + for (int i = 0; i < instructions.length; i++) { + Instruction instr = instructions[i]; + int[] targets = instr.getBranchTargets(); + for (int j = 0; j < targets.length; j++) { + addBackEdge(targets[j], i); + } + ExceptionHandler[] hs = handlers[i]; + for (int j = 0; j < hs.length; j++) { + addBackEdge(hs[j].handler, i); + } + liveLocals[i] = new BitSet(); + } + + for (int i = 0; i < backEdges.length; i++) { + int[] back = backEdges[i]; + if (back != null && back[back.length - 1] < 0) { + int j = back.length; + while (back[j - 1] < 0) { + j--; + } + int[] newBack = new int[j]; + System.arraycopy(back, 0, newBack, 0, newBack.length); + backEdges[i] = newBack; + } + } + + for (int i = 0; i < instructions.length; i++) { + Instruction instr = instructions[i]; + if (instr instanceof LoadInstruction) { + addLiveVar(i, ((LoadInstruction) instr).getVarIndex()); + } + } + } + + private String getAndCheckLocalType(int i, int l) { + String[] lts = localTypes[i]; + String t = TYPE_unknown; + if (l < lts.length) { + t = lts[l]; + } + if (t.equals(TYPE_null) || t.equals(TYPE_unknown)) { + throw new IllegalArgumentException("Cannot split oversized method because local " + l + " is undefined at " + i); + } + return t; + } + + private void allocateLocals(int count) { + if (maxLocals < allocatedLocals + count * 2) { + maxLocals = allocatedLocals + count * 2; + } + } + + private HelperPatch makeHelperPatch(int start, int len, int retVar, int unreadStack, int untouchedStack) { + String retType = retVar >= 0 ? getAndCheckLocalType(start + len, retVar) : "V"; + + ArrayList callWrapper = new ArrayList(); + int curStackLen = stackTypes[start].length; + + StringBuffer sigBuf = new StringBuffer(); + sigBuf.append("("); + // spill needed stack variables to allocated locals; + allocateLocals(curStackLen - unreadStack); + for (int i = curStackLen - 1; i >= unreadStack; i--) { + if (i < untouchedStack) { + callWrapper.add(DupInstruction.make(0)); + } + callWrapper.add(StoreInstruction.make(stackTypes[start][i], allocatedLocals + 2 * (i - unreadStack))); + } + // push needed locals + BitSet liveVars = liveLocals[start]; + for (int i = 0; i < liveVars.length(); i++) { + if (liveVars.get(i)) { + String t = getAndCheckLocalType(start, i); + sigBuf.append(t); + callWrapper.add(LoadInstruction.make(t, i)); + if (Util.getWordSize(t) > 1) { + i++; + } + } else { + // dummy + sigBuf.append("I"); + callWrapper.add(ConstantInstruction.make(0)); + } + } + // push stack variables + for (int i = unreadStack; i < curStackLen; i++) { + callWrapper.add(LoadInstruction.make(stackTypes[start][i], allocatedLocals + 2 * (i - unreadStack))); + sigBuf.append(stackTypes[start][i]); + if (Util.getWordSize(stackTypes[start][i]) == 2) { + sigBuf.append("I"); + callWrapper.add(ConstantInstruction.make(0)); + } + } + sigBuf.append(")"); + sigBuf.append(retType); + String sig = sigBuf.toString(); + + String name = createHelperMethod(true, sig); + + callWrapper.add(InvokeInstruction.make(sig, classType, name, IInvokeInstruction.Dispatch.STATIC)); + + int savedMaxStack = maxStack; + maxStack += curStackLen - unreadStack; + + int prefixLength = 4 * (curStackLen - unreadStack); + byte[] initialStack = new byte[curStackLen - unreadStack]; + for (int i = 0; i < initialStack.length; i++) { + initialStack[i] = Util.getWordSize(stackTypes[start][unreadStack + i]); + } + if (!outputInstructions(start, start + len, prefixLength, false, initialStack)) { + throw new Error("Helper function is overlarge"); + } + byte[] newCode = new byte[code.length + (retVar >= 0 ? 5 : 1)]; + for (int i = 0; i < curStackLen - unreadStack; i++) { + int local = allocatedLocals + i * 2; + newCode[i * 4] = (byte) OP_wide; + newCode[i * 4 + 1] = (byte) LoadInstruction.make(stackTypes[start][i + unreadStack], 500).getOpcode(); + newCode[i * 4 + 2] = (byte) (local >> 8); + newCode[i * 4 + 3] = (byte) local; + } + System.arraycopy(code, prefixLength, newCode, prefixLength, code.length - prefixLength); + int suffixOffset = code.length; + if (retVar >= 0) { + newCode[suffixOffset] = (byte) OP_wide; + newCode[suffixOffset + 1] = (byte) LoadInstruction.make(retType, 500).getOpcode(); + newCode[suffixOffset + 2] = (byte) (retVar >> 8); + newCode[suffixOffset + 3] = (byte) retVar; + newCode[suffixOffset + 4] = (byte) ReturnInstruction.make(retType).getOpcode(); + callWrapper.add(StoreInstruction.make(retType, retVar)); + } else { + newCode[suffixOffset] = (byte) ReturnInstruction.make(TYPE_void).getOpcode(); + } + + if (callWrapper.size() > len) { + return null; + } + + int[] rawHandlers = buildRawHandlers(start, start + len); + int[] bytecodeMap = buildBytecodeMap(start, start + len); + + auxMethods.add(new Output(name, sig, newCode, rawHandlers, bytecodeMap, maxLocals, maxStack, true)); + + maxStack = savedMaxStack; + + Instruction[] patch = new Instruction[callWrapper.size()]; + callWrapper.toArray(patch); + + ExceptionHandler[] startHS = handlers[start]; + ArrayList newHS = new ArrayList(); + for (int i = 0; i < startHS.length; i++) { + int t = startHS[i].handler; + if (t < start || t >= start + len) { + newHS.add(startHS[i]); + } + } + ExceptionHandler[] patchHS = new ExceptionHandler[newHS.size()]; + newHS.toArray(patchHS); + + return new HelperPatch(start, len, patch, patchHS); + } + + private HelperPatch findBlock(int start, int len) { + while (len > 100) { + // make sure there is at most one entry + int lastInvalid = start - 1; + for (int i = start + 1; i < start + len; i++) { + int[] back = backEdges[i]; + boolean outsideBranch = false; + for (int j = 0; back != null && j < back.length; j++) { + if (back[j] < start || back[j] >= start + len) { + outsideBranch = true; + } + } + if (outsideBranch) { + HelperPatch p = findBlock(lastInvalid + 1, i - lastInvalid - 1); + if (p != null) { + return p; + } + lastInvalid = i; + } + } + if (lastInvalid >= start) { + return null; + } + + // make sure there is at most one exit (fall through at the end) + if (!instructions[start + len - 1].isFallThrough()) { + len--; + continue; + } + lastInvalid = start - 1; + for (int i = start; i < start + len; i++) { + int[] targets = instructions[i].getBranchTargets(); + boolean outsideBranch = false; + if (instructions[i] instanceof ReturnInstruction) { + outsideBranch = true; + } + for (int j = 0; j < targets.length; j++) { + if (targets[j] < start || targets[j] >= start + len) { + outsideBranch = true; + } + } + if (outsideBranch) { + HelperPatch p = findBlock(lastInvalid + 1, i - lastInvalid - 1); + if (p != null) { + return p; + } + lastInvalid = i; + } + } + if (lastInvalid >= start) { + return null; + } + + lastInvalid = start - 1; + for (int i = start; i < start + len; i++) { + boolean out = false; + ExceptionHandler[] hs = handlers[i]; + for (int j = 0; j < hs.length; j++) { + int h = hs[j].handler; + if (h < start || h >= start + len) { + out = true; + } + } + int[] targets = instructions[i].getBranchTargets(); + for (int j = 0; j < targets.length; j++) { + int t = targets[j]; + if (t < start || t >= start + len) { + out = true; + } + } + if (out) { + HelperPatch p = findBlock(lastInvalid + 1, i - lastInvalid - 1); + if (p != null) { + return p; + } + lastInvalid = i; + } + } + + if (lastInvalid >= start) { + return null; + } + + if (stackTypes[start] == null) { + while (stackTypes[start] == null && len > 0) { + start++; + len--; + } + continue; + } + + // See how many stack elements at entry are still there, unchanged, at + // exit + int untouchedStack = Integer.MAX_VALUE; + // See how many elements of that part of the stack are never even read + int unreadStack = Integer.MAX_VALUE; + for (int i = start; i < start + len; i++) { + if (stackTypes[i] == null) { + untouchedStack = 0; + unreadStack = 0; + break; + } + int lowWaterMark = stackTypes[i].length - instructions[i].getPoppedCount(); + unreadStack = Math.min(unreadStack, lowWaterMark); + if (instructions[i] instanceof DupInstruction) { + // dup instructions don't actually pop off/change the element they + // duplicate + lowWaterMark += instructions[i].getPoppedCount(); + } + untouchedStack = Math.min(untouchedStack, lowWaterMark); + } + + if (untouchedStack > unreadStack + 1 || (untouchedStack == unreadStack + 1 && untouchedStack < stackTypes[start].length)) { + // we can only handle 1 read-but-untouched element + start++; + len--; + continue; + } + + // make sure we know the type of all the stack values that must be passed + // in + boolean unknownType = false; + for (int i = unreadStack; i < untouchedStack; i++) { + String t = stackTypes[start][i]; + if (t == null || t.equals(TYPE_unknown) || t.equals(TYPE_null)) { + unknownType = true; + break; + } + } + if (unknownType) { + start++; + len--; + continue; + } + + // make sure outgoing stack size is no more than the untouched stack size. + if (stackTypes[start + len] == null || stackTypes[start + len].length > untouchedStack) { + // This is a little conservative. We might be able to stop sooner with a + // valid + // extractable method, because changing 'len' might mean we have more + // untouched stack elements. But we'll do this in a dumb way to avoid + // being caught in some N^2 loop looking for extractable code. + while (len > 0 && stackTypes[start + len] == null || stackTypes[start + len].length > untouchedStack) { + len--; + } + continue; + } + + // make sure at most one local is defined and live on exit + BitSet liveAtEnd = (BitSet) liveLocals[start + len]; + boolean multipleDefs = false; + int localDefed = -1; + int firstDef = -1; + int secondDef = -1; + for (int i = start; i < start + len; i++) { + Instruction instr = instructions[i]; + if (instr instanceof StoreInstruction) { + int l = ((StoreInstruction) instr).getVarIndex(); + if (liveAtEnd.get(l) && l != localDefed) { + if (localDefed < 0) { + localDefed = l; + firstDef = i; + } else { + multipleDefs = true; + secondDef = i; + break; + } + } + } + } + + if (multipleDefs) { + HelperPatch p = findBlock(start, secondDef - start); + if (p != null) { + return p; + } + len = (start + len) - (firstDef + 1); + start = firstDef + 1; + continue; + } + + // make sure that the same external handlers are used all the way through + ExceptionHandler[] startHS = handlers[start]; + int numOuts = 0; + for (int j = 0; j < startHS.length; j++) { + int t = startHS[j].handler; + if (t < start || t >= start + len) { + numOuts++; + } + } + boolean mismatchedHandlers = false; + int firstMismatch = -1; + for (int i = start + 1; i < start + len; i++) { + ExceptionHandler[] hs = handlers[i]; + int matchingOuts = 0; + for (int j = 0; j < hs.length; j++) { + int t = hs[j].handler; + if (t < start || t >= start + len) { + boolean match = false; + for (int k = 0; k < startHS.length; k++) { + if (startHS[k].equals(hs[j])) { + match = true; + break; + } + } + if (match) { + matchingOuts++; + } + } + } + if (matchingOuts != numOuts) { + firstMismatch = i; + mismatchedHandlers = true; + break; + } + } + if (mismatchedHandlers) { + HelperPatch p = findBlock(start, firstMismatch - start); + if (p != null) { + return p; + } + start = firstMismatch; + continue; + } + + // all conditions satisfied, extract the code + try { + HelperPatch p = makeHelperPatch(start, len, localDefed, unreadStack, untouchedStack); + if (p == null) { + // something went wrong. Probably the code to call the helper ended up + // being + // bigger than the original code we extracted! + return null; + } else { + return p; + } + } catch (IllegalArgumentException ex) { + return null; + } + } + + return null; + } + + private void makeHelpers() { + int offset = 0; + ArrayList patches = new ArrayList(); + + while (offset + 5000 < instructions.length) { + HelperPatch p = findBlock(offset, 5000); + if (p != null) { + patches.add(p); + offset = p.start + p.length; + } else { + offset += 500; + } + } + + for (Iterator i = patches.iterator(); i.hasNext();) { + HelperPatch p = i.next(); + + System.arraycopy(p.code, 0, instructions, p.start, p.code.length); + for (int j = 0; j < p.length; j++) { + int index = j + p.start; + if (j < p.code.length) { + instructions[index] = p.code[j]; + } else { + instructions[index] = PopInstruction.make(0); // nop + } + handlers[index] = p.handlers; + instructionsToBytecodes[index] = -1; + } + } + } + + private void makeTypes() { + Verifier v = new Verifier(isStatic, classType, signature, instructions, handlers); + if (hierarchy != null) { + v.setClassHierarchy(hierarchy); + } + try { + v.computeTypes(); + } catch (Verifier.FailureException ex) { + throw new IllegalArgumentException("Cannot split oversized method because verification failed: " + ex.getMessage()); + } + localTypes = v.getLocalTypes(); + stackTypes = v.getStackTypes(); + } + + /** + * Do the work of generating new bytecodes. + * + * In pathological cases this could throw an Error, when the code you passed + * in is too large to fit into a single JVM method and Compiler can't find a + * way to break it up into helper methods. You probably won't encounter this + * unless you try to make it happen :-). + */ + final public void compile() { + collectInstructionInfo(); + + computeStackWords(); + + if (!outputInstructions(0, instructions.length, 0, false, null)) { + allocatedLocals = maxLocals; + makeLiveLocals(); + makeTypes(); + auxMethods = new ArrayList(); + makeHelpers(); + + computeStackWords(); + if (!outputInstructions(0, instructions.length, 0, false, null)) { + throw new Error("Input code too large; consider breaking up your code"); + } + } + mainMethod = new Output(null, null, code, buildRawHandlers(0, instructions.length), buildBytecodeMap(0, instructions.length), + maxLocals, maxStack, isStatic); + + instructionsToOffsets = null; + branchTargets = null; + stackWords = null; + code = null; + } + + /** + * Get the output bytecodes and other information for the method. + */ + final public Output getOutput() { + return mainMethod; + } + + /** + * Get bytecodes and other information for any helper methods that are + * required to implement the main method. These helpers represent code that + * could not be fit into the main method because of JVM method size + * constraints. + */ + final public Output[] getAuxiliaryMethods() { + if (auxMethods == null) { + return null; + } else { + Output[] r = new Output[auxMethods.size()]; + auxMethods.toArray(r); + return r; + } + } + + /** + * This class represents a method generated by a Compiler. One input method to + * the Compiler can generate multiple Outputs (if the input method is too big + * to be represented by a single method in the JVM, say if it requires more + * than 64K bytecodes). + */ + public final static class Output { + private byte[] code; + private int[] rawHandlers; + private int[] newBytecodesToOldBytecodes; + private String name; + private String signature; + private boolean isStatic; + private int maxLocals; + private int maxStack; + + Output(String name, String signature, byte[] code, int[] rawHandlers, int[] newBytecodesToOldBytecodes, int maxLocals, + int maxStack, boolean isStatic) { + this.code = code; + this.name = name; + this.signature = signature; + this.rawHandlers = rawHandlers; + this.newBytecodesToOldBytecodes = newBytecodesToOldBytecodes; + this.isStatic = isStatic; + this.maxLocals = maxLocals; + this.maxStack = maxStack; + } + + /** + * @return the actual bytecodes + */ + public byte[] getCode() { + return code; + } + + /** + * @return the name of the method; either "null", if this code takes the + * place of the original method, or some string representing the + * name of a helper method + */ + public String getMethodName() { + return name; + } + + /** + * @return the method signature in JVM format + */ + public String getMethodSignature() { + return signature; + } + + /** + * @return the access flags that should be used for this method, or 0 if + * this is the code for the original method + */ + public int getAccessFlags() { + return name != null ? (ACC_PRIVATE | (isStatic ? ACC_STATIC : 0)) : 0; + } + + /** + * @return the raw exception handler table in JVM format + */ + public int[] getRawHandlers() { + return rawHandlers; + } + + /** + * @return whether the method is static + */ + public boolean isStatic() { + return isStatic; + } + + /** + * @return a map m such that the new bytecode instruction at offset i + * corresponds to the bytecode instruction at m[i] in the original + * method + */ + public int[] getNewBytecodesToOldBytecodes() { + return newBytecodesToOldBytecodes; + } + + /** + * @return the maximum stack size in words as required by the JVM + */ + public int getMaxStack() { + return maxStack; + } + + /** + * @return the maximum local variable size in words as required by the JVM + */ + public int getMaxLocals() { + return maxLocals; + } + } +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/ConditionalBranchInstruction.java b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/ConditionalBranchInstruction.java new file mode 100644 index 000000000..e3726594f --- /dev/null +++ b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/ConditionalBranchInstruction.java @@ -0,0 +1,123 @@ +/******************************************************************************* + * 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.shrikeBT; + +/** + * This class represents conditional branches. A conditional branch tests two + * integers or two object references for some relationship, and takes the branch + * if the relationship holds. + */ +public final class ConditionalBranchInstruction extends Instruction { + + public interface IOperator {}; + + public enum Operator implements IOperator { + EQ, NE, LT, GE, GT, LE; + + @Override + public String toString() { + return super.toString().toLowerCase(); + } + } + + private int label; + + protected ConditionalBranchInstruction(short opcode, int label) { + this.opcode = opcode; + this.label = label; + } + + public static ConditionalBranchInstruction make(String type, Operator operator, int label) { + int t = Util.getTypeIndex(type); + short opcode; + + switch (t) { + case TYPE_int_index: + opcode = (short) (OP_if_icmpeq + (operator.ordinal() - Operator.EQ.ordinal())); + break; + case TYPE_Object_index: + if (operator != Operator.EQ && operator != Operator.NE) { + throw new IllegalArgumentException("Cannot test for condition " + operator + " on a reference"); + } + opcode = (short) (OP_if_acmpeq + (operator.ordinal() - Operator.EQ.ordinal())); + break; + default: + throw new IllegalArgumentException("Cannot conditionally branch on a value of type " + type); + } + + return make(opcode, label); + } + + //Relax from private to public by Xiangyu, to create ifeq + public static ConditionalBranchInstruction make(short opcode, int label) { + return new ConditionalBranchInstruction(opcode, label); + } + + public boolean equals(Object o) { + if (o instanceof ConditionalBranchInstruction) { + ConditionalBranchInstruction i = (ConditionalBranchInstruction) o; + return i.opcode == opcode && i.label == label; + } else { + return false; + } + } + + public String toString() { + return "ConditionalBranch(" + getType() + "," + getOperator() + "," + label + ")"; + } + + public int[] getBranchTargets() { + int[] r = { label }; + return r; + } + + public int getTarget() { + return label; + } + + public Instruction redirectTargets(int[] targetMap) { + return make(opcode, targetMap[label]); + } + + public Operator getOperator() { + if (opcode < OP_if_acmpeq) { + return Operator.values()[opcode - OP_if_icmpeq]; + } else { + return Operator.values()[opcode - OP_if_acmpeq]; + } + } + + public String getType() { + return opcode < OP_if_acmpeq ? TYPE_int : TYPE_Object; + } + + public int hashCode() { + return 30190 * opcode + 384101 * label; + } + + public int getPoppedCount() { + //Xiangyu, to support if_eq (if_ne)... + if (opcode >= Constants.OP_ifeq && opcode <= Constants.OP_ifle) + return 1; + return 2; + } + + public void visit(Visitor v) { + v.visitConditionalBranch(this); + } + + /* (non-Javadoc) + * @see com.ibm.domo.cfg.IInstruction#isPEI() + */ + public boolean isPEI() { + return false; + } +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/ConstantInstruction.java b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/ConstantInstruction.java new file mode 100644 index 000000000..5d650fbdd --- /dev/null +++ b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/ConstantInstruction.java @@ -0,0 +1,553 @@ +/******************************************************************************* + * 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.shrikeBT; + +/** + * A ConstantInstruction pushes some constant value onto the stack. + */ +public abstract class ConstantInstruction extends Instruction { + ConstantInstruction() { + } + + ConstantPoolReader getLazyConstantPool() { + return null; + } + + int getCPIndex() { + return 0; + } + + final static class ConstNull extends ConstantInstruction { + protected ConstNull() { + opcode = OP_aconst_null; + } + + private final static ConstNull preallocated = new ConstNull(); + + static ConstNull makeInternal() { + return preallocated; + } + + public Object getValue() { + return null; + } + + public String getType() { + return TYPE_null; + } + } + + static class ConstInt extends ConstantInstruction { + protected int value; + + private final static ConstInt[] preallocated = preallocate(); + + protected ConstInt(short opcode, int value) { + this.opcode = opcode; + this.value = value; + } + + private static ConstInt[] preallocate() { + ConstInt[] r = new ConstInt[256]; + for (int i = 0; i < r.length; i++) { + r[i] = new ConstInt(OP_bipush, i - 128); + } + for (int i = -1; i <= 5; i++) { + r[i + 128] = new ConstInt((short) (i - (-1) + OP_iconst_m1), i); + } + return r; + } + + static ConstInt makeInternal(int i) { + if (((byte) i) == i) { + return preallocated[i + 128]; + } else if (((short) i) == i) { + return new ConstInt(OP_sipush, i); + } else { + return new ConstInt(OP_ldc_w, i); + } + } + + final public Object getValue() { + return new Integer(getIntValue()); + } + + final public String getType() { + return TYPE_int; + } + + public int getIntValue() { + return value; + } + } + + final static class LazyInt extends ConstInt { + private ConstantPoolReader cp; + private int index; + private boolean isSet; + + protected LazyInt(short opcode, ConstantPoolReader cp, int index) { + super(opcode, 0); + this.cp = cp; + this.index = index; + this.isSet = false; + } + + public int getIntValue() { + if (!isSet) { + value = cp.getConstantPoolInteger(index); + isSet = true; + } + return value; + } + + public ConstantPoolReader getLazyConstantPool() { + return cp; + } + + public int getCPIndex() { + return index; + } + } + + static class ConstLong extends ConstantInstruction { + protected long value; + + private final static ConstLong[] preallocated = preallocate(); + + protected ConstLong(short opcode, long value) { + this.opcode = opcode; + this.value = value; + } + + private static ConstLong[] preallocate() { + ConstLong[] r = { new ConstLong(OP_lconst_0, 0), new ConstLong(OP_lconst_1, 1) }; + return r; + } + + static ConstLong makeInternal(long v) { + if (v == 0 || v == 1) { + return preallocated[(int) v]; + } else { + return new ConstLong(OP_ldc2_w, v); + } + } + + final public Object getValue() { + return new Long(getLongValue()); + } + + final public String getType() { + return TYPE_long; + } + + public long getLongValue() { + return value; + } + } + + final static class LazyLong extends ConstLong { + private ConstantPoolReader cp; + private int index; + private boolean isSet; + + protected LazyLong(short opcode, ConstantPoolReader cp, int index) { + super(opcode, 0); + this.cp = cp; + this.index = index; + this.isSet = false; + } + + public long getLongValue() { + if (!isSet) { + value = cp.getConstantPoolLong(index); + isSet = true; + } + return value; + } + + public ConstantPoolReader getLazyConstantPool() { + return cp; + } + + public int getCPIndex() { + return index; + } + } + + static class ConstFloat extends ConstantInstruction { + protected float value; + + private final static ConstFloat[] preallocated = preallocate(); + + protected ConstFloat(short opcode, float value) { + this.opcode = opcode; + this.value = value; + } + + private static ConstFloat[] preallocate() { + ConstFloat[] r = { new ConstFloat(OP_fconst_0, 0), new ConstFloat(OP_fconst_1, 1), new ConstFloat(OP_fconst_2, 2) }; + return r; + } + + static ConstFloat makeInternal(float v) { + if (v == 0.0 || v == 1.0 || v == 2.0) { + return preallocated[(int) v]; + } else { + return new ConstFloat(OP_ldc_w, v); + } + } + + final public Object getValue() { + return new Float(getFloatValue()); + } + + final public String getType() { + return TYPE_float; + } + + public float getFloatValue() { + return value; + } + } + + final static class LazyFloat extends ConstFloat { + private ConstantPoolReader cp; + private int index; + private boolean isSet; + + protected LazyFloat(short opcode, ConstantPoolReader cp, int index) { + super(opcode, 0.0f); + this.cp = cp; + this.index = index; + this.isSet = false; + } + + public float getFloatValue() { + if (!isSet) { + value = cp.getConstantPoolFloat(index); + isSet = true; + } + return value; + } + + public ConstantPoolReader getLazyConstantPool() { + return cp; + } + + public int getCPIndex() { + return index; + } + } + + static class ConstDouble extends ConstantInstruction { + protected double value; + + private final static ConstDouble[] preallocated = preallocate(); + + protected ConstDouble(short opcode, double value) { + this.opcode = opcode; + this.value = value; + } + + private static ConstDouble[] preallocate() { + ConstDouble[] r = { new ConstDouble(OP_dconst_0, 0), new ConstDouble(OP_dconst_1, 1) }; + return r; + } + + static ConstDouble makeInternal(double v) { + if (v == 0.0 || v == 1.0) { + return preallocated[(int) v]; + } else { + return new ConstDouble(OP_ldc2_w, v); + } + } + + final public Object getValue() { + return new Double(getDoubleValue()); + } + + final public String getType() { + return TYPE_double; + } + + public double getDoubleValue() { + return value; + } + } + + final static class LazyDouble extends ConstDouble { + private ConstantPoolReader cp; + private int index; + private boolean isSet; + + protected LazyDouble(short opcode, ConstantPoolReader cp, int index) { + super(opcode, 0.0); + this.cp = cp; + this.index = index; + this.isSet = false; + } + + public double getDoubleValue() { + if (!isSet) { + value = cp.getConstantPoolDouble(index); + isSet = true; + } + return value; + } + + public ConstantPoolReader getLazyConstantPool() { + return cp; + } + + public int getCPIndex() { + return index; + } + } + + static class ConstString extends ConstantInstruction { + protected String value; + + protected ConstString(short opcode, String value) { + this.opcode = opcode; + this.value = value; + } + + static ConstString makeInternal(String v) { + return new ConstString(OP_ldc_w, v); + } + + public Object getValue() { + return value; + } + + final public String getType() { + return TYPE_String; + } + } + + final static class LazyString extends ConstString { + private ConstantPoolReader cp; + private int index; + + protected LazyString(short opcode, ConstantPoolReader cp, int index) { + super(opcode, null); + this.cp = cp; + this.index = index; + } + + public Object getValue() { + if (value == null) { + value = cp.getConstantPoolString(index); + } + return value; + } + + public ConstantPoolReader getLazyConstantPool() { + return cp; + } + + public int getCPIndex() { + return index; + } + } + + static class ConstClass extends ConstantInstruction { + protected String typeName; + + protected ConstClass(short opcode, String typeName) { + this.opcode = opcode; + this.typeName = typeName; + } + + static ConstClass makeInternal(String v) { + return new ConstClass(OP_ldc_w, v); + } + + public Object getValue() { + return typeName; + } + + final public String getType() { + return TYPE_Class; + } + } + + final static class LazyClass extends ConstClass { + private ConstantPoolReader cp; + private int index; + + protected LazyClass(short opcode, ConstantPoolReader cp, int index) { + super(opcode, null); + this.cp = cp; + this.index = index; + } + + public Object getValue() { + if (typeName == null) { + typeName = cp.getConstantPoolClassType(index); + } + return typeName; + } + + public ConstantPoolReader getLazyConstantPool() { + return cp; + } + + public int getCPIndex() { + return index; + } + } + + /** + * @return the constant value pushed: an Integer, a Long, a Float, a Double, a + * String, or null + */ + public abstract Object getValue(); + + /** + * @return the type of the value pushed + */ + public abstract String getType(); + + public static ConstantInstruction make(String type, Object constant) { + if (constant == null) { + return ConstNull.makeInternal(); + } else if (type.equals(TYPE_String)) { + return makeString((String) constant); + } else if (type.equals(TYPE_Class)) { + return makeClass((String) constant); + } else { + switch (Util.getTypeIndex(type)) { + case TYPE_int_index: + return make(((Number) constant).intValue()); + case TYPE_long_index: + return make(((Number) constant).longValue()); + case TYPE_float_index: + return make(((Number) constant).floatValue()); + case TYPE_double_index: + return make(((Number) constant).doubleValue()); + default: + throw new IllegalArgumentException("Invalid type for constant: " + type); + } + } + } + + public static ConstantInstruction make(int i) { + return ConstInt.makeInternal(i); + } + + public static ConstantInstruction make(long l) { + return ConstLong.makeInternal(l); + } + + public static ConstantInstruction make(float f) { + return ConstFloat.makeInternal(f); + } + + public static ConstantInstruction make(double d) { + return ConstDouble.makeInternal(d); + } + + public static ConstantInstruction makeString(String s) { + return s == null ? (ConstantInstruction) ConstNull.makeInternal() : (ConstantInstruction) ConstString.makeInternal(s); + } + + public static ConstantInstruction makeClass(String s) { + return (ConstantInstruction) ConstClass.makeInternal(s); + } + + static ConstantInstruction make(ConstantPoolReader cp, int index) { + switch (cp.getConstantPoolItemType(index)) { + case CONSTANT_Integer: + return new LazyInt(OP_ldc_w, cp, index); + case CONSTANT_Long: + return new LazyLong(OP_ldc2_w, cp, index); + case CONSTANT_Float: + return new LazyFloat(OP_ldc_w, cp, index); + case CONSTANT_Double: + return new LazyDouble(OP_ldc2_w, cp, index); + case CONSTANT_String: + return new LazyString(OP_ldc_w, cp, index); + case CONSTANT_Class: + return new LazyClass(OP_ldc_w, cp, index); + default: + return null; + } + } + + final public boolean equals(Object o) { + if (o instanceof ConstantInstruction) { + ConstantInstruction i = (ConstantInstruction) o; + return i.getType().equals(getType()) && i.getValue().equals(getValue()); + } else { + return false; + } + } + + final public String getPushedType(String[] types) { + return getType(); + } + + final public byte getPushedWordSize() { + return Util.getWordSize(getType()); + } + + final public int hashCode() { + return getType().hashCode() + 14411 * getValue().hashCode(); + } + + final public void visit(Visitor v) { + v.visitConstant(this); + } + + private static String quote(Object o) { + if (o instanceof String) { + String s = (String) o; + StringBuffer buf = new StringBuffer("\""); + int len = s.length(); + for (int i = 0; i < len; i++) { + char ch = s.charAt(i); + switch (ch) { + case '"': + buf.append('\\'); + buf.append(ch); + break; + case '\n': + buf.append("\\\n"); + break; + case '\t': + buf.append("\\\t"); + break; + default: + buf.append(ch); + } + } + buf.append("\""); + return buf.toString(); + } else if (o == null) { + return "null"; + } else { + return o.toString(); + } + } + + final public String toString() { + return "Constant(" + getType() + "," + quote(getValue()) + ")"; + } + + /* (non-Javadoc) + * @see com.ibm.domo.cfg.IInstruction#isPEI() + */ + public boolean isPEI() { + return false; + } +} diff --git a/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/ConstantPoolReader.java b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/ConstantPoolReader.java new file mode 100644 index 000000000..b2facdc1f --- /dev/null +++ b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/ConstantPoolReader.java @@ -0,0 +1,113 @@ +/******************************************************************************* + * 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.shrikeBT; + +/** + * This class provides read-only access to a constant pool. It gets subclassed + * for each class reader/editor toolkit you want to work with. + */ +public abstract class ConstantPoolReader { + /** + * Retrieve the JVM constant pool item type (a Constants.CONSTANT_xxx value). + * This method should be overriden by a toolkit-specific subclass. + * + * @param index + * the constant pool item to examine + */ + public abstract int getConstantPoolItemType(int index); + + /** + * Retrieve the value of a CONSTANT_Integer constant pool item. This method + * should be overriden by a toolkit-specific subclass. + * + * @param index + * the constant pool item to examine + */ + public abstract int getConstantPoolInteger(int index); + + /** + * Retrieve the value of a CONSTANT_Float constant pool item. This method + * should be overriden by a toolkit-specific subclass. + * + * @param index + * the constant pool item to examine + */ + public abstract float getConstantPoolFloat(int index); + + /** + * Retrieve the value of a CONSTANT_Long constant pool item. This method + * should be overriden by a toolkit-specific subclass. + * + * @param index + * the constant pool item to examine + */ + public abstract long getConstantPoolLong(int index); + + /** + * Retrieve the value of a CONSTANT_Double constant pool item. This method + * should be overriden by a toolkit-specific subclass. + * + * @param index + * the constant pool item to examine + */ + public abstract double getConstantPoolDouble(int index); + + /** + * Retrieve the value of a CONSTANT_String constant pool item. This method + * should be overriden by a toolkit-specific subclass. + * + * @param index + * the constant pool item to examine + */ + public abstract String getConstantPoolString(int index); + + /** + * Retrieve the value of a CONSTANT_Class constant pool item in JVM internal + * class format (e.g., java/lang/Object). This method should be overriden by a + * toolkit-specific subclass. + * + * @param index + * the constant pool item to examine + */ + public abstract String getConstantPoolClassType(int index); + + /** + * Retrieve the class part of a CONSTANT_FieldRef, CONSTANT_MethodRef, or + * CONSTANT_InterfaceMethodRef constant pool item, in JVM internal class + * format (e.g., java/lang/Object). This method should be overriden by a + * toolkit-specific subclass. + * + * @param index + * the constant pool item to examine + */ + public abstract String getConstantPoolMemberClassType(int index); + + /** + * Retrieve the name part of a CONSTANT_FieldRef, CONSTANT_MethodRef, or + * CONSTANT_InterfaceMethodRef constant pool item, This method should be + * overriden by a toolkit-specific subclass. + * + * @param index + * the constant pool item to examine + */ + public abstract String getConstantPoolMemberName(int index); + + /** + * Retrieve the type part of a CONSTANT_FieldRef, CONSTANT_MethodRef, or + * CONSTANT_InterfaceMethodRef constant pool item, in JVM internal type format + * (e.g., Ljava/lang/Object;). This method should be overriden by a + * toolkit-specific subclass. + * + * @param index + * the constant pool item to examine + */ + public abstract String getConstantPoolMemberType(int index); +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/Constants.java b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/Constants.java new file mode 100644 index 000000000..a727e7092 --- /dev/null +++ b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/Constants.java @@ -0,0 +1,327 @@ +/******************************************************************************* + * 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.shrikeBT; + +/** + * This interface defines a bunch of constants from the JVM spec. It also + * defines some constants we need for other purposes. + * + * Here are the JVM constants: + *
                                + *
                              • The OP_ constants define the JVM instruction opcodes. + *
                              • The ACC_ constants define the accessibility flags for classes, fields + * and methods. + *
                              • The CONSTANT_ constants define the constant pool item types. + *
                              • The T_ constants define the types of arrays that can be created by + * OP_newarray. + *
                              • The TYPE_ constants define the string representations of various JVM + * types. Two special non-JVM types are defined, TYPE_null and TYPE_unknown, as + * noted below. + *
                              + * + * Non-JVM constants: + *
                                + *
                              • The OPR_ constants define the set of operators present in JVM + * instructions. + *
                              • The operatorNames array gives the string names of those operators. + *
                              • The TYPE_..._index constants define numeric representations of the JVM + * base types. + *
                              • The indexedTypes array maps those numeric representations to their + * official string representations. + *
                              • The indexedTypes_T array maps those numeric representations to the + * corresponding T_ constant. + *
                              + */ +public interface Constants { + + public static final short OP_nop = 0; + public static final short OP_aconst_null = 1; + public static final short OP_iconst_m1 = 2; + public static final short OP_iconst_0 = 3; + public static final short OP_iconst_1 = 4; + public static final short OP_iconst_2 = 5; + public static final short OP_iconst_3 = 6; + public static final short OP_iconst_4 = 7; + public static final short OP_iconst_5 = 8; + public static final short OP_lconst_0 = 9; + public static final short OP_lconst_1 = 10; + public static final short OP_fconst_0 = 11; + public static final short OP_fconst_1 = 12; + public static final short OP_fconst_2 = 13; + public static final short OP_dconst_0 = 14; + public static final short OP_dconst_1 = 15; + public static final short OP_bipush = 16; + public static final short OP_sipush = 17; + public static final short OP_ldc = 18; + public static final short OP_ldc_w = 19; + public static final short OP_ldc2_w = 20; + public static final short OP_iload = 21; + public static final short OP_lload = 22; + public static final short OP_fload = 23; + public static final short OP_dload = 24; + public static final short OP_aload = 25; + public static final short OP_iload_0 = 26; + public static final short OP_iload_1 = 27; + public static final short OP_iload_2 = 28; + public static final short OP_iload_3 = 29; + public static final short OP_lload_0 = 30; + public static final short OP_lload_1 = 31; + public static final short OP_lload_2 = 32; + public static final short OP_lload_3 = 33; + public static final short OP_fload_0 = 34; + public static final short OP_fload_1 = 35; + public static final short OP_fload_2 = 36; + public static final short OP_fload_3 = 37; + public static final short OP_dload_0 = 38; + public static final short OP_dload_1 = 39; + public static final short OP_dload_2 = 40; + public static final short OP_dload_3 = 41; + public static final short OP_aload_0 = 42; + public static final short OP_aload_1 = 43; + public static final short OP_aload_2 = 44; + public static final short OP_aload_3 = 45; + public static final short OP_iaload = 46; + public static final short OP_laload = 47; + public static final short OP_faload = 48; + public static final short OP_daload = 49; + public static final short OP_aaload = 50; + public static final short OP_baload = 51; + public static final short OP_caload = 52; + public static final short OP_saload = 53; + public static final short OP_istore = 54; + public static final short OP_lstore = 55; + public static final short OP_fstore = 56; + public static final short OP_dstore = 57; + public static final short OP_astore = 58; + public static final short OP_istore_0 = 59; + public static final short OP_istore_1 = 60; + public static final short OP_istore_2 = 61; + public static final short OP_istore_3 = 62; + public static final short OP_lstore_0 = 63; + public static final short OP_lstore_1 = 64; + public static final short OP_lstore_2 = 65; + public static final short OP_lstore_3 = 66; + public static final short OP_fstore_0 = 67; + public static final short OP_fstore_1 = 68; + public static final short OP_fstore_2 = 69; + public static final short OP_fstore_3 = 70; + public static final short OP_dstore_0 = 71; + public static final short OP_dstore_1 = 72; + public static final short OP_dstore_2 = 73; + public static final short OP_dstore_3 = 74; + public static final short OP_astore_0 = 75; + public static final short OP_astore_1 = 76; + public static final short OP_astore_2 = 77; + public static final short OP_astore_3 = 78; + public static final short OP_iastore = 79; + public static final short OP_lastore = 80; + public static final short OP_fastore = 81; + public static final short OP_dastore = 82; + public static final short OP_aastore = 83; + public static final short OP_bastore = 84; + public static final short OP_castore = 85; + public static final short OP_sastore = 86; + public static final short OP_pop = 87; + public static final short OP_pop2 = 88; + public static final short OP_dup = 89; + public static final short OP_dup_x1 = 90; + public static final short OP_dup_x2 = 91; + public static final short OP_dup2 = 92; + public static final short OP_dup2_x1 = 93; + public static final short OP_dup2_x2 = 94; + public static final short OP_swap = 95; + public static final short OP_iadd = 96; + public static final short OP_ladd = 97; + public static final short OP_fadd = 98; + public static final short OP_dadd = 99; + public static final short OP_isub = 100; + public static final short OP_lsub = 101; + public static final short OP_fsub = 102; + public static final short OP_dsub = 103; + public static final short OP_imul = 104; + public static final short OP_lmul = 105; + public static final short OP_fmul = 106; + public static final short OP_dmul = 107; + public static final short OP_idiv = 108; + public static final short OP_ldiv = 109; + public static final short OP_fdiv = 110; + public static final short OP_ddiv = 111; + public static final short OP_irem = 112; + public static final short OP_lrem = 113; + public static final short OP_frem = 114; + public static final short OP_drem = 115; + public static final short OP_ineg = 116; + public static final short OP_lneg = 117; + public static final short OP_fneg = 118; + public static final short OP_dneg = 119; + public static final short OP_ishl = 120; + public static final short OP_lshl = 121; + public static final short OP_ishr = 122; + public static final short OP_lshr = 123; + public static final short OP_iushr = 124; + public static final short OP_lushr = 125; + public static final short OP_iand = 126; + public static final short OP_land = 127; + public static final short OP_ior = 128; + public static final short OP_lor = 129; + public static final short OP_ixor = 130; + public static final short OP_lxor = 131; + public static final short OP_iinc = 132; + public static final short OP_i2l = 133; + public static final short OP_i2f = 134; + public static final short OP_i2d = 135; + public static final short OP_l2i = 136; + public static final short OP_l2f = 137; + public static final short OP_l2d = 138; + public static final short OP_f2i = 139; + public static final short OP_f2l = 140; + public static final short OP_f2d = 141; + public static final short OP_d2i = 142; + public static final short OP_d2l = 143; + public static final short OP_d2f = 144; + public static final short OP_i2b = 145; + public static final short OP_i2c = 146; + public static final short OP_i2s = 147; + public static final short OP_lcmp = 148; + public static final short OP_fcmpl = 149; + public static final short OP_fcmpg = 150; + public static final short OP_dcmpl = 151; + public static final short OP_dcmpg = 152; + public static final short OP_ifeq = 153; + public static final short OP_ifne = 154; + public static final short OP_iflt = 155; + public static final short OP_ifge = 156; + public static final short OP_ifgt = 157; + public static final short OP_ifle = 158; + public static final short OP_if_icmpeq = 159; + public static final short OP_if_icmpne = 160; + public static final short OP_if_icmplt = 161; + public static final short OP_if_icmpge = 162; + public static final short OP_if_icmpgt = 163; + public static final short OP_if_icmple = 164; + public static final short OP_if_acmpeq = 165; + public static final short OP_if_acmpne = 166; + public static final short OP_goto = 167; + public static final short OP_jsr = 168; + public static final short OP_ret = 169; + public static final short OP_tableswitch = 170; + public static final short OP_lookupswitch = 171; + public static final short OP_ireturn = 172; + public static final short OP_lreturn = 173; + public static final short OP_freturn = 174; + public static final short OP_dreturn = 175; + public static final short OP_areturn = 176; + public static final short OP_return = 177; + public static final short OP_getstatic = 178; + public static final short OP_putstatic = 179; + public static final short OP_getfield = 180; + public static final short OP_putfield = 181; + public static final short OP_invokevirtual = 182; + public static final short OP_invokespecial = 183; + public static final short OP_invokestatic = 184; + public static final short OP_invokeinterface = 185; + public static final short OP_xxxunusedxxx = 186; + public static final short OP_new = 187; + public static final short OP_newarray = 188; + public static final short OP_anewarray = 189; + public static final short OP_arraylength = 190; + public static final short OP_athrow = 191; + public static final short OP_checkcast = 192; + public static final short OP_instanceof = 193; + public static final short OP_monitorenter = 194; + public static final short OP_monitorexit = 195; + public static final short OP_wide = 196; + public static final short OP_multianewarray = 197; + public static final short OP_ifnull = 198; + public static final short OP_ifnonnull = 199; + public static final short OP_goto_w = 200; + public static final short OP_jsr_w = 201; + + public static final short ACC_PUBLIC = 0x1; + public static final short ACC_PRIVATE = 0x2; + public static final short ACC_PROTECTED = 0x4; + public static final short ACC_STATIC = 0x8; + public static final short ACC_FINAL = 0x10; + public static final short ACC_SYNCHRONIZED = 0x20; + public static final short ACC_SUPER = 0x20; + public static final short ACC_VOLATILE = 0x40; + public static final short ACC_TRANSIENT = 0x80; + public static final short ACC_NATIVE = 0x100; + public static final short ACC_INTERFACE = 0x200; + public static final short ACC_ABSTRACT = 0x400; + public static final short ACC_STRICT = 0x800; + + public static final byte CONSTANT_Utf8 = 1; + public static final byte CONSTANT_Integer = 3; + public static final byte CONSTANT_Float = 4; + public static final byte CONSTANT_Long = 5; + public static final byte CONSTANT_Double = 6; + public static final byte CONSTANT_Class = 7; + public static final byte CONSTANT_String = 8; + public static final byte CONSTANT_FieldRef = 9; + public static final byte CONSTANT_MethodRef = 10; + public static final byte CONSTANT_InterfaceMethodRef = 11; + public static final byte CONSTANT_NameAndType = 12; + + public static final byte T_BOOLEAN = 4; + public static final byte T_CHAR = 5; + public static final byte T_FLOAT = 6; + public static final byte T_DOUBLE = 7; + public static final byte T_BYTE = 8; + public static final byte T_SHORT = 9; + public static final byte T_INT = 10; + public static final byte T_LONG = 11; + + public static final String TYPE_boolean = "Z"; + public static final String TYPE_byte = "B"; + public static final String TYPE_int = "I"; + public static final String TYPE_short = "S"; + public static final String TYPE_long = "J"; + public static final String TYPE_float = "F"; + public static final String TYPE_double = "D"; + public static final String TYPE_char = "C"; + public static final String TYPE_void = "V"; + public static final String TYPE_String = "Ljava/lang/String;"; + public static final String TYPE_Object = "Ljava/lang/Object;"; + public static final String TYPE_Throwable = "Ljava/lang/Throwable;"; + public static final String TYPE_Class = "Ljava/lang/Class;"; + public static final String TYPE_Exception = "Ljava/lang/Exception;"; + public static final String TYPE_RuntimeException = "Ljava/lang/RuntimeException;"; + public static final String TYPE_Error = "Ljava/lang/Error;"; + + /** + * This represents the type of "null", which can be any object. It is not + * defined by the JVM spec. + */ + public static final String TYPE_null = "L;"; + /** This represents a type which is unknown. It is not defined by the JVM spec. */ + public static final String TYPE_unknown = "L?;"; + + public static final byte TYPE_int_index = 0; + public static final byte TYPE_long_index = 1; + public static final byte TYPE_float_index = 2; + public static final byte TYPE_double_index = 3; + public static final byte TYPE_Object_index = 4; + public static final byte TYPE_byte_index = 5; + public static final byte TYPE_char_index = 6; + public static final byte TYPE_short_index = 7; + public static final byte TYPE_boolean_index = 8; + + public static final String[] indexedTypes = { TYPE_int, TYPE_long, TYPE_float, TYPE_double, TYPE_Object, TYPE_byte, TYPE_char, + TYPE_short, TYPE_boolean }; + + public static final byte[] indexedTypes_T = { T_INT, T_LONG, T_FLOAT, T_DOUBLE, 0, T_BYTE, T_CHAR, T_SHORT, T_BOOLEAN }; + + // these constants are used by analyses to report results + public static final int NO = 1; + public static final int YES = 2; + public static final int MAYBE = 3; +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/ConversionInstruction.java b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/ConversionInstruction.java new file mode 100644 index 000000000..0c57100cb --- /dev/null +++ b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/ConversionInstruction.java @@ -0,0 +1,117 @@ +/******************************************************************************* + * 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.shrikeBT; + +/** + * This class represents instructions that convert from one primitive type to + * another. + */ +public final class ConversionInstruction extends Instruction { + private String fromType; + private String toType; + + protected ConversionInstruction(short opcode) { + this.opcode = opcode; + + if (opcode < OP_i2b) { + int k = opcode - OP_i2l; + toType = indexedTypes[skip(k % 3, k / 3)]; + } else { + toType = indexedTypes[(opcode - OP_i2b) + TYPE_byte_index]; + } + + if (opcode < OP_i2b) { + fromType = indexedTypes[(opcode - OP_i2l) / 3]; + } else { + fromType = TYPE_int; + } + } + + private final static ConversionInstruction[] preallocated = preallocate(); + + private static ConversionInstruction[] preallocate() { + ConversionInstruction[] r = new ConversionInstruction[OP_i2s - OP_i2l + 1]; + for (short i = OP_i2l; i <= OP_i2s; i++) { + r[i - OP_i2l] = new ConversionInstruction(i); + } + return r; + } + + public static ConversionInstruction make(String fromType, String toType) { + int from = Util.getTypeIndex(fromType); + int to = Util.getTypeIndex(toType); + if (from < 0 || from > TYPE_double_index) { + throw new IllegalArgumentException("Cannot convert from type " + fromType); + } + if (from == TYPE_int_index && (to >= TYPE_byte_index && to <= TYPE_short_index)) { + return preallocated[(OP_i2b - OP_i2l) + (to - TYPE_byte_index)]; + } else { + if (to < 0 || to > TYPE_double_index) { + throw new IllegalArgumentException("Cannot convert from type " + fromType + " to type " + toType); + } + if (to == from) { + throw new IllegalArgumentException("Cannot convert from type " + fromType + " to same type"); + } + return preallocated[from * 3 + (to > from ? to - 1 : to)]; + } + } + + public int getPoppedCount() { + return 1; + } + + public String getFromType() { + return fromType; + } + + private static int skip(int a, int b) { + return a < b ? a : a + 1; + } + + public String getToType() { + return toType; + } + + public String getPushedType(String[] types) { + return getToType(); + } + + public byte getPushedWordSize() { + return Util.getWordSize(getToType()); + } + + public boolean equals(Object o) { + if (o instanceof ConversionInstruction) { + ConversionInstruction i = (ConversionInstruction) o; + return i.opcode == opcode; + } else { + return false; + } + } + + public int hashCode() { + return opcode * 143111; + } + + public String toString() { + return "Conversion(" + getFromType() + "," + getToType() + ")"; + } + + public void visit(Visitor v) { + v.visitConversion(this); + } + /* (non-Javadoc) + * @see com.ibm.domo.cfg.IInstruction#isPEI() + */ + public boolean isPEI() { + return false; + } +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/Decoder.java b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/Decoder.java new file mode 100644 index 000000000..0d24b9c9d --- /dev/null +++ b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/Decoder.java @@ -0,0 +1,1085 @@ +/******************************************************************************* + * 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.shrikeBT; + +import java.util.ArrayList; + +import com.ibm.wala.shrikeBT.BinaryOpInstruction.Operator; + +/** + * A Decoder translates a method's Java bytecode into shrikeBT code, i.e. an + * array of Instruction objects and an array of lists of ExceptionHandlers. + * + * This class implements basic decoding functionality. A toolkit for reading + * class files must specialize this class with particular constant pool reader + * implementation. + * + * Normal usage of this class looks like this: + * + *
                              + * 
                              + *    Decoder d = new MyToolkitDecoder(...);
                              + *    try {
                              + *      d.decode();
                              + *    } catch (Decoder.InvalidBytecodeException ex) {
                              + *      ...
                              + *    }
                              + *    Instruction[] myInstructions = d.getInstructions();
                              + *    ExceptionHandler[][] exnHandlers = d.getHandlers();
                              + *  
                              + * 
                              + */ +public abstract class Decoder implements Constants { + private static final int UNSEEN = -1; + private static final int INSIDE_INSTRUCTION = -2; + + private static int skip(int a, int b) { + return a < b ? a : a + 1; + } + + private final static ExceptionHandler[] noHandlers = new ExceptionHandler[0]; + + /** This holds predecoded instructions for the single-byte instructions. */ + private final static Instruction[] simpleInstructions = makeSimpleInstructions(); + + private static Instruction[] makeSimpleInstructions() { + Instruction[] table = new Instruction[256]; + + table[OP_aconst_null] = ConstantInstruction.make(TYPE_null, null); + for (int i = OP_iconst_m1; i <= OP_iconst_5; i++) { + table[i] = ConstantInstruction.make(TYPE_int, new Integer(i - OP_iconst_m1 - 1)); + } + for (int i = OP_lconst_0; i <= OP_lconst_1; i++) { + table[i] = ConstantInstruction.make(TYPE_long, new Long(i - OP_lconst_0)); + } + for (int i = OP_fconst_0; i <= OP_fconst_2; i++) { + table[i] = ConstantInstruction.make(TYPE_float, new Float(i - OP_fconst_0)); + } + for (int i = OP_dconst_0; i <= OP_dconst_1; i++) { + table[i] = ConstantInstruction.make(TYPE_double, new Double(i - OP_dconst_0)); + } + + for (int i = OP_iload_0; i <= OP_aload_3; i++) { + table[i] = LoadInstruction.make(indexedTypes[(i - OP_iload_0) / 4], (i - OP_iload_0) % 4); + } + for (int i = OP_iaload; i <= OP_saload; i++) { + table[i] = ArrayLoadInstruction.make(indexedTypes[i - OP_iaload]); + } + for (int i = OP_istore_0; i <= OP_astore_3; i++) { + table[i] = StoreInstruction.make(indexedTypes[(i - OP_istore_0) / 4], (i - OP_istore_0) % 4); + } + for (int i = OP_iastore; i <= OP_sastore; i++) { + table[i] = ArrayStoreInstruction.make(indexedTypes[i - OP_iastore]); + } + + table[OP_pop] = PopInstruction.make(1); + table[OP_dup] = DupInstruction.make(1, 0); + table[OP_dup_x1] = DupInstruction.make(1, 1); + table[OP_swap] = SwapInstruction.make(); + + for (int i = OP_iadd; i <= OP_drem; i++) { + table[i] = BinaryOpInstruction.make(indexedTypes[(i - OP_iadd) % 4], BinaryOpInstruction.Operator.values()[(i - OP_iadd) / 4]); + } + for (int i = OP_ineg; i <= OP_dneg; i++) { + table[i] = UnaryOpInstruction.make(indexedTypes[i - OP_ineg], UnaryOpInstruction.Operator.NEG); + } + for (int i = OP_ishl; i <= OP_lushr; i++) { + table[i] = ShiftInstruction.make(indexedTypes[(i - OP_ishl) % 2], ShiftInstruction.Operator.values()[(i - OP_ishl) / 2]); + } + for (int i = OP_iand; i <= OP_lxor; i++) { + table[i] = BinaryOpInstruction.make(indexedTypes[(i - OP_iand) % 2], BinaryOpInstruction.Operator.values()[BinaryOpInstruction.Operator.AND.ordinal() + (i - OP_iand) / 2]); + } + + for (int i = OP_i2l; i <= OP_d2f; i++) { + table[i] = ConversionInstruction.make(indexedTypes[(i - OP_i2l) / 3], indexedTypes[skip((i - OP_i2l) % 3, (i - OP_i2l) / 3)]); + } + for (int i = OP_i2b; i <= OP_i2s; i++) { + table[i] = ConversionInstruction.make(TYPE_int, indexedTypes[5 + (i - OP_i2b)]); + } + + table[OP_lcmp] = ComparisonInstruction.make(TYPE_long, ComparisonInstruction.Operator.CMP); + for (int i = OP_fcmpl; i <= OP_dcmpg; i++) { + table[i] = ComparisonInstruction.make(indexedTypes[2 + (i - OP_fcmpl) / 2], ComparisonInstruction.Operator.values()[ComparisonInstruction.Operator.CMPL.ordinal() + (i - OP_fcmpl) % 2]); + } + + for (int i = OP_ireturn; i <= OP_areturn; i++) { + table[i] = ReturnInstruction.make(indexedTypes[i - OP_ireturn]); + } + table[OP_return] = ReturnInstruction.make(TYPE_void); + + table[OP_athrow] = ThrowInstruction.make(); + + table[OP_monitorenter] = MonitorInstruction.make(true); + table[OP_monitorexit] = MonitorInstruction.make(false); + + table[OP_arraylength] = ArrayLengthInstruction.make(); + + return table; + } + + private static final Instruction makeZero = ConstantInstruction.make(0); + + // Holds the result of decoding + private Instruction[] instructions; + private ExceptionHandler[][] handlers; + private int[] instructionsToBytecodes; + private ConstantPoolReader constantPool; + + // Holds the input to decode + private byte[] code; + private int[] rawHandlers; + + // Temporary working data + private int[] decodedOffset; + private byte[] decodedSize; + private ArrayList decoded; + private int[] belongsToSub; + private int[] JSRs; + private RetInfo[] retInfo; + + /** + * This constructor is only supposed to be used by subclasses. + * + * @param code + * the bytecodes for a method as per JVM spec + * @param rawHandlers + * flattened array of (startPC, endPC, targetPC, classIndex) tuples + * defined as per the JVM spec + */ + protected Decoder(byte[] code, int[] rawHandlers, ConstantPoolReader cp) { + this.code = code; + this.rawHandlers = rawHandlers; + this.constantPool = cp; + } + + public ConstantPoolReader getConstantPool() { + return constantPool; + } + + private int decodeShort(int index) { + return (code[index] << 8) | (code[index + 1] & 0xFF); + } + + private int decodeUShort(int index) { + return ((code[index] & 0xFF) << 8) | (code[index + 1] & 0xFF); + } + + private int decodeInt(int index) { + return (code[index] << 24) | ((code[index + 1] & 0xFF) << 16) | ((code[index + 2] & 0xFF) << 8) | (code[index + 3] & 0xFF); + } + + private Instruction makeConstantPoolLoad(int index) throws InvalidBytecodeException { + ConstantInstruction ci = ConstantInstruction.make(constantPool, index); + if (ci == null) { + throw new InvalidBytecodeException("Constant pool item at index " + index + " (type " + + constantPool.getConstantPoolItemType(index) + ") cannot be loaded"); + } + return ci; + } + + private static int elemCount(byte[] stack, int stackPtr) throws InvalidBytecodeException { + if (stackPtr < 0) { + throw new InvalidBytecodeException("Stack underflow"); + } + + if (stack[stackPtr] == 2) { + return 1; + } else { + if (stackPtr < 1) { + throw new InvalidBytecodeException("Stack underflow"); + } + + if (stack[stackPtr - 1] != 1) { + throw new InvalidBytecodeException("Trying to manipulate a pair of " + "one-word items but one of them is two words"); + } + + return 2; + } + } + + private String getPrimitiveType(int t) throws InvalidBytecodeException { + switch (t) { + case T_BOOLEAN: + return TYPE_boolean; + case T_CHAR: + return TYPE_char; + case T_FLOAT: + return TYPE_float; + case T_DOUBLE: + return TYPE_double; + case T_BYTE: + return TYPE_byte; + case T_SHORT: + return TYPE_short; + case T_INT: + return TYPE_int; + case T_LONG: + return TYPE_long; + default: + throw new InvalidBytecodeException("Unknown primitive type " + t); + } + } + + private static class RetInfo { + int sub; + int retVar; + int stackLen; + byte[] stackWords; + + RetInfo(int sub, int retVar, int stackLen, byte[] stackWords) { + this.sub = sub; + this.retVar = retVar; + this.stackLen = stackLen; + this.stackWords = stackWords; + } + } + + private boolean doesSubroutineReturn(int sub) { + for (int j = 0; j < retInfo.length; j++) { + if (retInfo[j] != null && retInfo[j].sub == sub) { + return true; + } + } + return false; + } + + private int findReturnToVar(int v, int addr, boolean[] visited) throws InvalidBytecodeException { + while (true) { + if (visited[addr]) { + return 0; + } else if (retInfo[addr] != null && retInfo[addr].retVar == v) { + return addr; + } else { + int offset = decodedOffset[addr]; + + if (offset == UNSEEN) { + return 0; + } + + int size = decodedSize[addr]; + Instruction instr = null; + + visited[addr] = true; + + for (int j = 0; j < rawHandlers.length; j += 4) { + if (rawHandlers[j] <= addr && addr < rawHandlers[j + 1]) { + int handlerAddr = rawHandlers[j + 2]; + + if (decodedOffset[handlerAddr] < 0) { + byte[] stackWords = new byte[code.length * 2]; + + decodeAt(handlerAddr, 1, stackWords); + } + + int r = findReturnToVar(v, handlerAddr, visited); + if (r != 0) { + return r; + } + } + } + + // If there's a JSR here, see if it ever returns. If it does not + // then this instruction does not fall through and so we should + // stop searching. + if (JSRs[addr] != 0) { + if (!doesSubroutineReturn(JSRs[addr])) { + return 0; + } + } else { + for (int j = 0; j < size; j++) { + instr = decoded.get(offset + j); + if (instr instanceof StoreInstruction && ((StoreInstruction) instr).getVarIndex() == v) { + return 0; + } + + int[] targets = instr.getBranchTargets(); + for (int k = 0; k < targets.length; k++) { + if (targets[k] >= 0) { + int r = findReturnToVar(v, targets[k], visited); + if (r != 0) { + return r; + } + } + } + } + + if (instr != null && !instr.isFallThrough()) { + return 0; + } + } + + do { + addr++; + } while (decodedOffset[addr] == INSIDE_INSTRUCTION); + } + } + } + + /** + * Locate an instruction that returns from this subroutine; return 0 if one + * cannot be found. + */ + private int findReturn(int subAddr) throws InvalidBytecodeException { + if (decodedSize[subAddr] < 1) { + throw new InvalidBytecodeException("Subroutine at " + subAddr + " does not start with an astore or pop instruction"); + } + Instruction instr = decoded.get(decodedOffset[subAddr]); + + if (instr instanceof PopInstruction) { + // this subroutine can't return + return 0; + } + + if (!(instr instanceof StoreInstruction)) { + throw new InvalidBytecodeException("Subroutine at " + subAddr + " does not start with an astore or pop instruction"); + } + + int localIndex = ((StoreInstruction) instr).getVarIndex(); + + do { + subAddr++; + } while (decodedOffset[subAddr] == INSIDE_INSTRUCTION); + + return findReturnToVar(localIndex, subAddr, new boolean[code.length]); + } + + private void decodeSubroutine(int jsrAddr, int retToAddr, int subAddr, int stackLen, byte[] stackWords) + throws InvalidBytecodeException { + if (JSRs == null) { + JSRs = new int[code.length]; + retInfo = new RetInfo[code.length]; + } + + JSRs[jsrAddr] = subAddr; + + if (decodedOffset[subAddr] < 0) { + stackWords[stackLen] = 1; + stackLen++; + + decodeAt(subAddr, stackLen, stackWords); + } + + int retAddr = findReturn(subAddr); + if (retAddr > 0) { + RetInfo r = retInfo[retAddr]; + r.sub = subAddr; + decodeAt(retToAddr, r.stackLen, (byte[]) r.stackWords.clone()); + } + } + + private void assignReachablesToSubroutine(int addr, int sub) { + + while (belongsToSub[addr] < 0) { + int size = decodedSize[addr]; + + belongsToSub[addr] = sub; + + for (int j = 0; j < rawHandlers.length; j += 4) { + if (rawHandlers[j] <= addr && addr < rawHandlers[j + 1]) { + assignReachablesToSubroutine(rawHandlers[j + 2], sub); + } + } + + Instruction instr = null; + if (size > 0 && JSRs[addr] == 0) { + int offset = decodedOffset[addr]; + instr = decoded.get(offset + size - 1); + int[] targets = instr.getBranchTargets(); + for (int k = 0; k < targets.length; k++) { + if (targets[k] >= 0) { + // only chase real gotos; ignore rets + assignReachablesToSubroutine(targets[k], sub); + } + } + } + + if (instr != null && !instr.isFallThrough()) { + return; + } + if (JSRs[addr] != 0 && !doesSubroutineReturn(JSRs[addr])) { + return; + } + + do { + addr++; + } while (decodedOffset[addr] < 0); + } + } + + private void assignSubroutine(int sub) { + assignReachablesToSubroutine(sub, sub); + + for (int i = 0; i < belongsToSub.length; i++) { + if (JSRs[i] > 0 && belongsToSub[i] == sub && belongsToSub[JSRs[i]] < 0) { + assignSubroutine(JSRs[i]); + } + } + } + + private void computeSubroutineMap() { + belongsToSub = new int[code.length]; + + for (int i = 0; i < belongsToSub.length; i++) { + belongsToSub[i] = -1; + } + + assignSubroutine(0); + } + + private int decodeBytecodeInstruction(int index, int stackLen, byte[] stackWords) throws InvalidBytecodeException { + int opcode = code[index] & 0xFF; + + Instruction i = simpleInstructions[opcode]; + if (i != null) { + decoded.add(i); + return index + 1; + } + + boolean wide = false; + + while (true) { + index++; + + switch (opcode) { + case OP_nop: + break; + case OP_bipush: + i = ConstantInstruction.make(code[index]); + index++; + break; + case OP_sipush: + i = ConstantInstruction.make(decodeShort(index)); + index += 2; + break; + case OP_ldc: + i = makeConstantPoolLoad(code[index] & 0xFF); + index++; + break; + case OP_ldc_w: + i = makeConstantPoolLoad(decodeShort(index)); + index += 2; + break; + case OP_ldc2_w: + i = makeConstantPoolLoad(decodeShort(index)); + index += 2; + break; + case OP_iload: + case OP_lload: + case OP_fload: + case OP_dload: + case OP_aload: + i = LoadInstruction.make(indexedTypes[opcode - OP_iload], wide ? decodeUShort(index) : (code[index] & 0xFF)); + index += wide ? 2 : 1; + break; + case OP_istore: + case OP_lstore: + case OP_fstore: + case OP_dstore: + case OP_astore: + i = StoreInstruction.make(indexedTypes[opcode - OP_istore], wide ? decodeUShort(index) : (code[index] & 0xFF)); + index += wide ? 2 : 1; + break; + case OP_pop2: + i = PopInstruction.make(elemCount(stackWords, stackLen - 1)); + break; + case OP_dup_x2: + i = DupInstruction.make(1, elemCount(stackWords, stackLen - 2)); + break; + case OP_dup2: + i = DupInstruction.make(elemCount(stackWords, stackLen - 1), 0); + break; + case OP_dup2_x1: + i = DupInstruction.make(elemCount(stackWords, stackLen - 1), 1); + break; + case OP_dup2_x2: + i = DupInstruction.make(elemCount(stackWords, stackLen - 1), elemCount(stackWords, stackLen - 2)); + break; + case OP_iinc: { + int v = wide ? decodeUShort(index) : (code[index] & 0xFF); + int c = wide ? decodeShort(index + 2) : code[index + 1]; + + decoded.add(LoadInstruction.make(TYPE_int, v)); + decoded.add(ConstantInstruction.make(c)); + decoded.add(BinaryOpInstruction.make(TYPE_int, Operator.ADD)); + i = StoreInstruction.make(TYPE_int, v); + index += wide ? 4 : 2; + break; + } + case OP_ifeq: + case OP_ifne: + case OP_iflt: + case OP_ifle: + case OP_ifgt: + case OP_ifge: + decoded.add(makeZero); + i = ConditionalBranchInstruction.make(TYPE_int, ConditionalBranchInstruction.Operator.values()[opcode - OP_ifeq], (index - 1) + decodeShort(index)); + index += 2; + break; + case OP_if_icmpeq: + case OP_if_icmpne: + case OP_if_icmplt: + case OP_if_icmple: + case OP_if_icmpgt: + case OP_if_icmpge: + i = ConditionalBranchInstruction.make((short) opcode, (index - 1) + decodeShort(index)); + index += 2; + break; + case OP_if_acmpeq: + case OP_if_acmpne: + i = ConditionalBranchInstruction.make(TYPE_Object, ConditionalBranchInstruction.Operator.values()[opcode - OP_if_acmpeq], (index - 1) + + decodeShort(index)); + index += 2; + break; + case OP_goto: + i = GotoInstruction.make((index - 1) + decodeShort(index)); + index += 2; + break; + case OP_jsr: { + index += 2; + break; + } + case OP_jsr_w: { + index += 4; + break; + } + case OP_ret: + int v = wide ? decodeUShort(index) : (code[index] & 0xFF); + i = GotoInstruction.make(-1 - v); + + if (retInfo == null) { + throw new InvalidBytecodeException("'ret' outside of subroutine"); + } + retInfo[index - (wide ? 2 : 1)] = new RetInfo(-1, v, stackLen, stackWords); + + index += wide ? 2 : 1; + break; + case OP_tableswitch: { + int start = index - 1; + while ((index & 3) != 0) { + index++; + } + int def = start + decodeInt(index); + int low = decodeInt(index + 4); + int high = decodeInt(index + 8); + int[] t = new int[(high - low + 1) * 2]; + + for (int j = 0; j < t.length; j += 2) { + t[j] = j / 2 + low; + t[j + 1] = start + decodeInt(index + 12 + j * 2); + } + i = SwitchInstruction.make(t, def); + index += 12 + (high - low + 1) * 4; + break; + } + case OP_lookupswitch: { + int start = index - 1; + while ((index & 3) != 0) { + index++; + } + int def = start + decodeInt(index); + int n = decodeInt(index + 4); + int[] t = new int[n * 2]; + + for (int j = 0; j < t.length; j += 2) { + t[j] = decodeInt(index + 8 + j * 4); + t[j + 1] = start + decodeInt(index + 12 + j * 4); + } + i = SwitchInstruction.make(t, def); + index += 8 + n * 8; + break; + } + case OP_getstatic: + case OP_getfield: { + int f = decodeUShort(index); + i = GetInstruction.make(constantPool, f, opcode == OP_getstatic); + index += 2; + break; + } + case OP_putstatic: + case OP_putfield: { + int f = decodeUShort(index); + i = PutInstruction.make(constantPool, f, opcode == OP_putstatic); + index += 2; + break; + } + case OP_invokevirtual: + case OP_invokespecial: + case OP_invokestatic: { + int m = decodeUShort(index); + i = InvokeInstruction.make(constantPool, m, opcode); + index += 2; + break; + } + case OP_invokeinterface: { + int m = decodeUShort(index); + i = InvokeInstruction.make(constantPool, m, opcode); + index += 4; + break; + } + case OP_new: + i = NewInstruction.make(constantPool.getConstantPoolClassType(decodeUShort(index)), 0); + index += 2; + break; + case OP_newarray: + i = NewInstruction.make(Util.makeArray(getPrimitiveType(code[index])), 1); + index++; + break; + case OP_anewarray: + i = NewInstruction.make(Util.makeArray(constantPool.getConstantPoolClassType(decodeUShort(index))), 1); + index += 2; + break; + case OP_checkcast: + i = CheckCastInstruction.make(constantPool.getConstantPoolClassType(decodeUShort(index))); + index += 2; + break; + case OP_instanceof: + i = InstanceofInstruction.make(constantPool.getConstantPoolClassType(decodeUShort(index))); + index += 2; + break; + case OP_wide: + wide = true; + opcode = code[index] & 0xFF; + continue; + case OP_multianewarray: + i = NewInstruction.make(constantPool.getConstantPoolClassType(decodeUShort(index)), code[index + 2] & 0xFF); + index += 3; + break; + case OP_ifnull: + case OP_ifnonnull: + decoded.add(ConstantInstruction.make(TYPE_Object, null)); + i = ConditionalBranchInstruction.make(TYPE_Object, ConditionalBranchInstruction.Operator.values()[opcode - OP_ifnull], (index - 1) + decodeShort(index)); + index += 2; + break; + case OP_goto_w: + i = GotoInstruction.make((index - 1) + decodeInt(index)); + index += 4; + break; + default: + throw new InvalidBytecodeException("Unknown opcode " + opcode); + } + + break; + } + + if (i != null) { + decoded.add(i); + } + + return index; + } + + private int applyInstructionToStack(Instruction i, int stackLen, byte[] stackWords) throws InvalidBytecodeException { + stackLen -= i.getPoppedCount(); + + if (stackLen < 0) { + throw new InvalidBytecodeException("Stack underflow"); + } + + if (i instanceof DupInstruction) { + DupInstruction d = (DupInstruction) i; + int delta = d.getDelta(); + int size = d.getSize(); + + System.arraycopy(stackWords, stackLen + delta, stackWords, stackLen + size + delta, size); + System.arraycopy(stackWords, stackLen, stackWords, stackLen + size, delta); + System.arraycopy(stackWords, stackLen + size + delta, stackWords, stackLen, size); + stackLen += size * 2 + delta; + } else if (i instanceof SwapInstruction) { + if (stackWords[stackLen] != stackWords[stackLen + 1]) { + throw new Error("OP_swap must always be swapping the same size, 1"); + } + stackLen += 2; + } else { + byte pushedWords = i.getPushedWordSize(); + if (pushedWords > 0) { + stackWords[stackLen] = pushedWords; + stackLen++; + } + } + + return stackLen; + } + + private void decodeAt(int index, int stackLen, byte[] stackWords) throws InvalidBytecodeException { + if (index < 0 || index >= decodedOffset.length) { + throw new InvalidBytecodeException(index, "Branch index " + index + " out of range"); + } + + while (decodedOffset[index] < 0) { + int s = decoded.size(); + + decodedOffset[index] = s; + + int newIndex; + + try { + newIndex = decodeBytecodeInstruction(index, stackLen, stackWords); + int instrCount = decoded.size() - s; + + decodedSize[index] = (byte) instrCount; + + // mark invalid offsets + for (int i = index + 1; i < newIndex; i++) { + decodedOffset[i] = INSIDE_INSTRUCTION; + } + + if (instrCount > 0) { + for (int i = s; i < s + instrCount; i++) { + stackLen = applyInstructionToStack(decoded.get(i), stackLen, stackWords); + } + + Instruction instr = decoded.get(s + instrCount - 1); + int[] targets = instr.getBranchTargets(); + + for (int i = 0; i < targets.length; i++) { + int t = targets[i]; + + if (t >= 0) { + decodeAt(t, stackLen, (byte[]) stackWords.clone()); + } + } + + if (!instr.isFallThrough()) { + return; + } + } else { // possibly the jsr case + int jIndex = index; + int opcode = code[jIndex] & 0xFF; + if (opcode == OP_wide) { + jIndex++; + opcode = code[jIndex] & 0xFF; + } + + if (opcode == OP_jsr || opcode == OP_jsr_w) { + jIndex++; + int offset = opcode == OP_jsr_w ? decodeInt(jIndex) : decodeShort(jIndex); + + decoded.add(GotoInstruction.make(0)); + decodedSize[index] = 1; + + decodeSubroutine(index, newIndex, index + offset, stackLen, stackWords); + return; + } + } + } catch (InvalidBytecodeException ex) { + ex.setIndex(index); + throw ex; + } catch (Error ex) { + System.err.println("Fatal error at index " + index); + throw ex; + } catch (RuntimeException ex) { + System.err.println("Fatal error at index " + index); + throw ex; + } + + index = newIndex; + + if (index >= decodedOffset.length) { + throw new InvalidBytecodeException(index, "Fell off end of bytecode array"); + } + } + } + + /** + * This exception is thrown when the Decoder detects invalid incoming bytecode + * (code that would not pass the Java verifier). We don't guarantee to perform + * full verification in the Decoder, however. + */ + public static class InvalidBytecodeException extends Exception { + + private static final long serialVersionUID = -8807125136613458111L; + private int index; + + InvalidBytecodeException(String s) { + super(s); + index = -1; + } + + InvalidBytecodeException(int i, String s) { + super(s); + index = i; + } + + void setIndex(int i) { + if (index < 0) { + index = i; + } + } + + /** + * @return the offset of the bytecode instruction deemed to be invalid + */ + public int getIndex() { + return index; + } + } + + private ExceptionHandler[] makeHandlers(int i, int[] addrMap) { + int numHandlers = 0; + for (int j = 0; j < rawHandlers.length; j += 4) { + if (rawHandlers[j] <= i && i < rawHandlers[j + 1]) { + numHandlers++; + } + } + + return makeHandlers(i, numHandlers, addrMap); + } + + private ExceptionHandler[] makeHandlers(int i, int numHandlers, int[] addrMap) { + if (numHandlers == 0) { + return noHandlers; + } else { + ExceptionHandler[] hs = new ExceptionHandler[numHandlers]; + numHandlers = 0; + for (int j = 0; j < rawHandlers.length; j += 4) { + if (rawHandlers[j] <= i && i < rawHandlers[j + 1]) { + int classIndex = rawHandlers[j + 3]; + String catchClass = classIndex == 0 ? null : constantPool.getConstantPoolClassType(classIndex); + + hs[numHandlers] = new ExceptionHandler(addrMap[rawHandlers[j + 2]], catchClass); + numHandlers++; + } + } + return hs; + } + } + + private int computeSubroutineLength(int sub) { + int len = 1; // extra instruction for "push null" + + for (int i = sub; i < belongsToSub.length; i++) { + if (belongsToSub[i] == sub) { + len += decodedSize[i]; + if (JSRs[i] > 0) { + len += computeSubroutineLength(JSRs[i]); + } + } + } + + return len; + } + + private int appendSubroutineCode(int callSite, int newCodeIndex, int[] callerMap) { + instructions[callerMap[callSite]] = GotoInstruction.make(newCodeIndex); + + instructions[newCodeIndex] = ConstantInstruction.make(TYPE_Object, null); + newCodeIndex++; + + int subStart = newCodeIndex; + int[] map = (int[]) callerMap.clone(); + int sub = JSRs[callSite]; + + // emit the subroutine code + for (int i = sub; i < belongsToSub.length; i++) { + if (belongsToSub[i] == sub) { + int s = decodedSize[i]; + int offset = decodedOffset[i]; + + map[i] = newCodeIndex; + + for (int j = 0; j < s; j++) { + Instruction instr = decoded.get(offset + j); + instructions[newCodeIndex] = instr; + instructionsToBytecodes[newCodeIndex] = i; + newCodeIndex++; + } + } + } + + // fix up branch targets within emitted subroutine + for (int i = subStart; i < newCodeIndex; i++) { + Instruction instr = instructions[i]; + if (instr instanceof GotoInstruction && ((GotoInstruction) instr).getLabel() < 0) { + // fix up 'ret' instruction to branch back to return address + instructions[i] = GotoInstruction.make(callerMap[callSite] + 1); + } else { + instructions[i] = instr.redirectTargets(map); + } + handlers[i] = makeHandlers(instructionsToBytecodes[i], map); + } + + // extend handlers to cover the fake "push null" + handlers[subStart - 1] = handlers[subStart]; + + // resolve callee subroutines + for (int i = sub; i < belongsToSub.length; i++) { + if (belongsToSub[i] == sub && JSRs[i] > 0) { + newCodeIndex = appendSubroutineCode(i, newCodeIndex, map); + } + } + + return newCodeIndex; + } + + /** + * Perform the decoding. + * + * @throws InvalidBytecodeException + * the incoming code is invalid and would fail Java bytecode + * verification + */ + final public void decode() throws InvalidBytecodeException { + byte[] stackWords = new byte[code.length * 2]; + + decoded = new ArrayList(); + decodedOffset = new int[code.length]; + for (int i = 0; i < decodedOffset.length; i++) { + decodedOffset[i] = UNSEEN; + } + decodedSize = new byte[code.length]; + + decodeAt(0, 0, stackWords); + // Decode code that's only reachable through exception handlers + for (int i = 0; i < rawHandlers.length; i += 4) { + stackWords[0] = 1; + decodeAt(rawHandlers[i + 2], 1, stackWords); + } + + if (retInfo != null) { + computeSubroutineMap(); + retInfo = null; + } + + int instructionsLen = decoded.size(); + + if (belongsToSub != null) { + for (int i = 0; i < belongsToSub.length; i++) { + if (belongsToSub[i] == 0) { + if (JSRs[i] > 0) { + instructionsLen += computeSubroutineLength(JSRs[i]); + } + } else if (belongsToSub[i] > 0) { + instructionsLen -= decodedSize[i]; + } + } + } + + instructions = new Instruction[instructionsLen]; + instructionsToBytecodes = new int[instructionsLen]; + handlers = new ExceptionHandler[instructionsLen][]; + + // shuffle decoded instructions into method order + int p = 0; + for (int i = 0; i < decodedOffset.length; i++) { + int offset = decodedOffset[i]; + + if (offset >= 0 && (belongsToSub == null || belongsToSub[i] == 0)) { + decodedOffset[i] = p; + + int s = decodedSize[i]; + for (int j = 0; j < s; j++) { + instructions[p] = decoded.get(offset + j); + instructionsToBytecodes[p] = i; + p++; + } + } + } + + // fix up instructions to refer to the instruction vector instead of + // bytecode offsets + for (int i = 0; i < p; i++) { + instructions[i] = instructions[i].redirectTargets(decodedOffset); + } + + // emit subroutines + if (JSRs != null) { + for (int i = 0; i < JSRs.length; i++) { + if (JSRs[i] > 0 && belongsToSub[i] == 0) { + p = appendSubroutineCode(i, p, decodedOffset); + } + } + } + + // generate exception handlers + if (rawHandlers.length > 0) { + ExceptionHandler[] hs = null; + int handlersValidBefore = -1; + + p = 0; + for (int i = 0; i < decodedOffset.length; i++) { + if (decodedOffset[i] >= 0 && (belongsToSub == null || belongsToSub[i] == 0)) { + if (i >= handlersValidBefore) { + // We just crossed a handler range boundary + // compute new exception handler array + int numHandlers = 0; + handlersValidBefore = Integer.MAX_VALUE; + for (int j = 0; j < rawHandlers.length; j += 4) { + if (rawHandlers[j] <= i) { + if (i < rawHandlers[j + 1]) { + numHandlers++; + handlersValidBefore = Math.min(handlersValidBefore, rawHandlers[j + 1]); + } + } else { + handlersValidBefore = Math.min(handlersValidBefore, rawHandlers[j]); + } + } + + hs = makeHandlers(i, numHandlers, decodedOffset); + } + + int s = decodedSize[i]; + for (int j = 0; j < s; j++) { + handlers[p] = hs; + p++; + } + } + } + } else { + for (int i = 0; i < handlers.length; i++) { + handlers[i] = noHandlers; + } + } + + decoded = null; + decodedOffset = null; + decodedSize = null; + belongsToSub = null; + JSRs = null; + } + + /** + * Get the decoded instructions. + * + * @return array of decoded instructions + */ + final public Instruction[] getInstructions() { + if (instructions == null) { + throw new Error("Call decode() before calling getInstructions()"); + } + return instructions; + } + + /** + * Get the decoded exception handlers. + * + * @return array of exception handler lists + */ + final public ExceptionHandler[][] getHandlers() { + if (handlers == null) { + throw new Error("Call decode() before calling getHandlers()"); + } + return handlers; + } + + /** + * Get the mapping between instructions and input bytecodes. + * + * @return an array m such that m[i] is the offset of the bytecode instruction + * which gave rise to the Instruction referenced in the instructions + * array at offset i + */ + final public int[] getInstructionsToBytecodes() { + if (instructionsToBytecodes == null) { + throw new Error("Call decode() before calling getInstructionsToBytecodes()"); + } + return instructionsToBytecodes; + } +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/Disassembler.java b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/Disassembler.java new file mode 100644 index 000000000..938eb74e0 --- /dev/null +++ b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/Disassembler.java @@ -0,0 +1,60 @@ +/******************************************************************************* + * 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.shrikeBT; + +import java.io.IOException; +import java.io.Writer; + +/** + * This is a very simple component to disassemble a ShrikeBT method. The + * disassembly is just the list of ShrikeBT instructions, annotated with + * exception handler blocks and the mapping back to the original bytecodes. + */ +public class Disassembler { + private Instruction[] instructions; + private ExceptionHandler[][] handlers; + private int[] instructionsToBytecodes; + + /** + * Create a disassembler for a method. + */ + public Disassembler(Instruction[] instructions, ExceptionHandler[][] handlers, int[] instructionsToBytecodes) { + this.instructions = instructions; + this.handlers = handlers; + this.instructionsToBytecodes = instructionsToBytecodes; + } + + /** + * Create a disassembler for a method. + */ + public Disassembler(MethodData data) { + this(data.getInstructions(), data.getHandlers(), data.getInstructionsToBytecodes()); + } + + /** + * Write the disassembly to a stream. Each line is prefixed with 'prefix'. + */ + public void disassembleTo(String prefix, Writer w) throws IOException { + for (int j = 0; j < instructions.length; j++) { + w.write(prefix + j + ": " + instructions[j] + " (" + instructionsToBytecodes[j] + ")\n"); + for (int k = 0; k < handlers[j].length; k++) { + w.write(prefix + " Handles " + handlers[j][k].catchClass + " at " + handlers[j][k].handler + "\n"); + } + } + } + + /** + * Write the disassembly to a stream. + */ + public void disassembleTo(Writer w) throws IOException { + disassembleTo("", w); + } +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/DupInstruction.java b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/DupInstruction.java new file mode 100644 index 000000000..72eae5a5d --- /dev/null +++ b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/DupInstruction.java @@ -0,0 +1,106 @@ +/******************************************************************************* + * 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.shrikeBT; + +/** + * This class represents dup instructions. There are two kinds of dup + * instructions, dup and dup_x1: + * + * dup: a::rest => a::a::rest dup_x1: a::b::rest => a::b::a::rest + */ +public final class DupInstruction extends Instruction { + private int size; + private byte delta; + + protected DupInstruction(byte size, byte delta) { + this.size = size; + this.delta = delta; + } + + private final static DupInstruction[] preallocated = preallocate(); + + private static DupInstruction[] preallocate() { + DupInstruction[] r = new DupInstruction[9]; + + for (int i = 0; i < r.length; i++) { + r[i] = new DupInstruction((byte) (i / 3), (byte) (i % 3)); + } + return r; + } + + /** + * DupInstructions with size or delta 2 might cause code generation failures + * when the working stack contains long or double values, when these + * DupInstructions cannot be easily translated into Java bytecode + * instructions. For safety, avoid using DupInstructions with size or delta 2. + * + * Don't create these outside the shrikeBT decoder. + */ + static DupInstruction make(int size, int delta) { + if (size < 0 || size > 2) { + throw new IllegalArgumentException("Invalid dup size: " + size); + } + if (delta < 0 || delta > 2) { + throw new IllegalArgumentException("Invalid dup delta: " + delta); + } + return preallocated[size * 3 + delta]; + } + + /** + * @param delta + * 0 for dup, 1 for dup_x1 + */ + public static DupInstruction make(int delta) { + if (delta < 0 || delta > 1) { + throw new IllegalArgumentException("Invalid dup delta: " + delta); + } + return make(1, delta); + } + + public boolean equals(Object o) { + if (o instanceof DupInstruction) { + DupInstruction i = (DupInstruction) o; + return i.size == size && i.delta == delta; + } else { + return false; + } + } + + public int getSize() { + return size; + } + + public int getDelta() { + return delta; + } + + public int hashCode() { + return size + 8431890 + 10 * delta; + } + + public int getPoppedCount() { + return size + delta; + } + + public String toString() { + return "Dup(" + size + "," + delta + ")"; + } + + public void visit(Visitor v) { + v.visitDup(this); + } + /* (non-Javadoc) + * @see com.ibm.domo.cfg.IInstruction#isPEI() + */ + public boolean isPEI() { + return false; + } +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/ExceptionHandler.java b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/ExceptionHandler.java new file mode 100644 index 000000000..f4888c5c5 --- /dev/null +++ b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/ExceptionHandler.java @@ -0,0 +1,84 @@ +/******************************************************************************* + * 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.shrikeBT; + +/** + * An ExceptionHandler represents a single handler covering a single + * instruction. It simply tells us what kind of exception to catch and where to + * dispatch the exception to. + * + * ExceptionHandlers are immutable. It is quite legal to save a reference to an + * exception handler and use it in any other context. We also treat arrays of + * ExceptionHandlers as immutable. Therefore the following code can be used to + * build an exception handler table that specifies two handlers covering an + * entire block of code: + * + *
                              + * 
                              + *  ExceptionHandler[] hs = {
                              + *    new ExceptionHandler(110, "Ljava.lang.NullPointerException;"),
                              + *    new ExceptionHandler(220, "Ljava.io.IOException;");
                              + *  };
                              + *  for (int i = 0; i < 100; i++) {
                              + *    handlers[i] = hs;
                              + *  }
                              + * 
                              + */ +final public class ExceptionHandler { + int handler; + String catchClass; + + /** + * @param handler + * the label for the handler code + * @param catchClass + * the type of exception that should be caught (in JVM format), or + * null if all exceptions should be caught (as with 'finally') + */ + public ExceptionHandler(int handler, String catchClass) { + this.handler = handler; + this.catchClass = catchClass; + } + + /** + * @return the label of the handler code + */ + public int getHandler() { + return handler; + } + + /** + * @return the type of exceptions to be caught, or null if all exceptions + * should be caught + */ + public String getCatchClass() { + return catchClass; + } + + public boolean equals(ExceptionHandler h) { + return h.handler == handler && (catchClass == null ? h.catchClass == null : catchClass.equals(h.catchClass)); + } + + /* (non-Javadoc) + * @see java.lang.Object#hashCode() + */ + public int hashCode() { + return 1069 * handler + ((catchClass == null) ? 0 : catchClass.hashCode()); + } + + public boolean equals(Object o) { + if (o instanceof ExceptionHandler) { + return equals((ExceptionHandler) o); + } else { + return false; + } + } +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/GetInstruction.java b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/GetInstruction.java new file mode 100644 index 000000000..b58053b63 --- /dev/null +++ b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/GetInstruction.java @@ -0,0 +1,145 @@ +/******************************************************************************* + * 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.shrikeBT; + +/** + * This class represents get and getstatic instructions. + */ +public class GetInstruction extends Instruction { + protected String type; + protected String classType; + protected String fieldName; + + GetInstruction(short opcode, String type, String classType, String fieldName) { + this.opcode = opcode; + this.type = type; + this.classType = classType; + this.fieldName = fieldName; + } + + ConstantPoolReader getLazyConstantPool() { + return null; + } + + final static class Lazy extends GetInstruction { + private ConstantPoolReader cp; + private int index; + + Lazy(short opcode, ConstantPoolReader cp, int index) { + super(opcode, null, null, null); + this.index = index; + this.cp = cp; + } + + ConstantPoolReader getLazyConstantPool() { + return cp; + } + + int getCPIndex() { + return index; + } + + public String getClassType() { + if (classType == null) { + classType = cp.getConstantPoolMemberClassType(index); + } + return classType; + } + + public String getFieldName() { + if (fieldName == null) { + fieldName = cp.getConstantPoolMemberName(index); + } + return fieldName; + } + + public String getFieldType() { + if (type == null) { + type = cp.getConstantPoolMemberType(index); + } + return type; + } + } + + static GetInstruction make(ConstantPoolReader cp, int index, boolean isStatic) { + return new Lazy(isStatic ? OP_getstatic : OP_getfield, cp, index); + } + + public static GetInstruction make(String type, String className, String fieldName, boolean isStatic) { + if (type == null) { + throw new NullPointerException("type must not be null"); + } + if (className == null) { + throw new NullPointerException("className must not be null"); + } + if (fieldName == null) { + throw new NullPointerException("fieldName must not be null"); + } + return new GetInstruction(isStatic ? OP_getstatic : OP_getfield, type, className, fieldName); + } + + final public boolean equals(Object o) { + if (o instanceof GetInstruction) { + GetInstruction i = (GetInstruction) o; + return i.getFieldType().equals(getFieldType()) && i.getClassType().equals(getClassType()) + && i.getFieldName().equals(getFieldName()) && i.opcode == opcode; + } else { + return false; + } + } + + public String getClassType() { + return classType; + } + + public String getFieldName() { + return fieldName; + } + + public String getFieldType() { + return type; + } + + final public boolean isStatic() { + return opcode == OP_getstatic; + } + + final public int hashCode() { + return getClassType().hashCode() + 11113 * getFieldType().hashCode() + 398011 * getFieldName().hashCode() + opcode; + } + + final public int getPoppedCount() { + return isStatic() ? 0 : 1; + } + + final public String getPushedType(String[] types) { + return getFieldType(); + } + + final public byte getPushedWordSize() { + return Util.getWordSize(getFieldType()); + } + + public String toString() { + return "Get(" + getFieldType() + "," + (isStatic() ? "STATIC" : "NONSTATIC") + "," + getClassType() + "," + getFieldName() + + ")"; + } + + public void visit(Visitor v) { + v.visitGet(this); + } + /* (non-Javadoc) + * @see com.ibm.domo.cfg.IInstruction#isPEI() + */ + public boolean isPEI() { + return true; + } +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/GotoInstruction.java b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/GotoInstruction.java new file mode 100644 index 000000000..2c1362ab5 --- /dev/null +++ b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/GotoInstruction.java @@ -0,0 +1,85 @@ +/******************************************************************************* + * 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.shrikeBT; + +/** + * This class represents goto and goto_w instructions. + */ +public final class GotoInstruction extends Instruction { + private int[] label; + + protected GotoInstruction(int label) { + int[] l = { label }; + this.label = l; + this.opcode = OP_goto; + } + + private final static GotoInstruction[] preallocated = preallocate(); + + private static GotoInstruction[] preallocate() { + GotoInstruction[] r = new GotoInstruction[256]; + for (int i = 0; i < r.length; i++) { + r[i] = new GotoInstruction(i); + } + return r; + } + + public static GotoInstruction make(int label) { + if (0 <= label && label < preallocated.length) { + return preallocated[label]; + } else { + return new GotoInstruction(label); + } + } + + public boolean isFallThrough() { + return false; + } + + public int[] getBranchTargets() { + return label; + } + + public int getLabel() { + return label[0]; + } + + public Instruction redirectTargets(int[] targetMap) { + return make(targetMap[label[0]]); + } + + public boolean equals(Object o) { + if (o instanceof GotoInstruction) { + GotoInstruction i = (GotoInstruction) o; + return i.label == label; + } else { + return false; + } + } + + public int hashCode() { + return label[0] * 1348091 + 18301; + } + + public String toString() { + return "Goto(" + getLabel() + ")"; + } + + public void visit(Visitor v) { + v.visitGoto(this); + } + /* (non-Javadoc) + * @see com.ibm.domo.cfg.IInstruction#isPEI() + */ + public boolean isPEI() { + return false; + } +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/IInstruction.java b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/IInstruction.java new file mode 100644 index 000000000..0845e61ce --- /dev/null +++ b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/IInstruction.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * 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.shrikeBT; + +/** + * @author sfink + * + * Basic functionality we expect of any instruction implementation + */ +public interface IInstruction { + + /** + * PEI == "Potentially excepting instruction" + * @return true iff this instruction might throw an exception + */ + boolean isPEI(); + +} diff --git a/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/IInvokeInstruction.java b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/IInvokeInstruction.java new file mode 100644 index 000000000..6638c591b --- /dev/null +++ b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/IInvokeInstruction.java @@ -0,0 +1,34 @@ +/******************************************************************************* + * 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.shrikeBT; + + +/** + * @author sfink + * + * Basic functionality any invoke instruction should provide + */ +public interface IInvokeInstruction extends IInstruction { + + + /** + * @return one of BytecodeConstants.INVOKE[SPECIAL|VIRTUAL|STATIC|INTERFACE] + */ + IDispatch getInvocationCode(); + + public interface IDispatch { + + } + + public static enum Dispatch implements IDispatch { + VIRTUAL, SPECIAL, STATIC, INTERFACE; + } +} diff --git a/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/InstanceofInstruction.java b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/InstanceofInstruction.java new file mode 100644 index 000000000..e4b19f18e --- /dev/null +++ b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/InstanceofInstruction.java @@ -0,0 +1,70 @@ +/******************************************************************************* + * 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.shrikeBT; + +/** + * This class represents instanceof instructions. + */ +public final class InstanceofInstruction extends Instruction { + private String type; + + protected InstanceofInstruction(String type) { + this.type = type; + this.opcode = OP_instanceof; + } + + public static InstanceofInstruction make(String type) { + return new InstanceofInstruction(type); + } + + public boolean equals(Object o) { + if (o instanceof InstanceofInstruction) { + InstanceofInstruction i = (InstanceofInstruction) o; + return i.type.equals(type); + } else { + return false; + } + } + + public int hashCode() { + return 31980190 + type.hashCode(); + } + + public int getPoppedCount() { + return 1; + } + + public String getType() { + return type; + } + + public String getPushedType(String[] types) { + return TYPE_boolean; + } + + public byte getPushedWordSize() { + return 1; + } + + public void visit(Visitor v) { + v.visitInstanceof(this); + } + + public String toString() { + return "Instanceof(" + type + ")"; + } + /* (non-Javadoc) + * @see com.ibm.domo.cfg.IInstruction#isPEI() + */ + public boolean isPEI() { + return false; + } +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/Instruction.java b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/Instruction.java new file mode 100644 index 000000000..7de9d8225 --- /dev/null +++ b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/Instruction.java @@ -0,0 +1,223 @@ +/******************************************************************************* + * 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.shrikeBT; + +/** + * Instructions are immutable objects. It is always legal to take a reference to + * an instruction and use it in any other context. You never need to copy + * instructions. It is often a good idea to keep references to frequently used + * instructions cached in static fields. + * + * To generate an Instruction, locate the class for the instruction you want to + * generate, and invoke the appropriate "make" static method on that class. The + * Util class has convenience methods for creating some of the more complex + * instructions using reflection to fill in some of the needed information + * (e.g., makeGet, makePut, makeInvoke). + * + * We simplify the bytecode instruction set a bit using some preprocessing and + * postprocessing: + * + * There is no 'iinc' instruction. 'iinc' instructions are expanded to 'iload; + * bipush; iadd; istore' during decoding and reassembled during compilation. + * + * There are no 'jsr' or 'ret' instructions. Bytecode subroutines are expanded + * inline during decoding. + * + * There are no 'ifeq', 'ifne', 'ifgt', 'ifge', 'iflt', 'ifle' instructions. + * These instructions are expanded to 'bipush 0; if_icmp' during decoding and + * reassembled during compilation. + * + * There are no 'ifnull' or 'ifnonnull' instructions. These instructions are + * expanded to 'aconst_null; if_acmp' during decoding and reassembled during + * compilation. + * + * All Java values, including longs and doubles, occupy just one word on the + * stack. Places where the JVM assumes differently are fixed up during + * compilation. However, longs and double still take up two local variable slots + * (this usually doesn't matter to instrumentation). + * + * Control transfer instructions refer to target instructions using integers. + * These integers are usually indices into an array of instructions. + */ +public abstract class Instruction implements Constants, Cloneable, IInstruction { + private final static int[] noInstructions = new int[0]; + + /** + * Ensure that only this package can subclass Instruction. + */ + Instruction() { + } + + short opcode = -1; + + /** + * @return true if the instruction can "fall through" to the following + * instruction + */ + public boolean isFallThrough() { + return true; + } + + /** + * @return an array containing the labels this instruction can branch to (not + * including the following instruction if this instruction 'falls + * through') + */ + public int[] getBranchTargets() { + return noInstructions; + } + + /** + * @return an Instruction equivalent to this one but with any branch labels + * updated by looking them up in the targetMap array + */ + public Instruction redirectTargets(int[] targetMap) { + return this; + } + + /** + * @return the number of values this instruction pops off the working stack + */ + public int getPoppedCount() { + return 0; + } + + /** + * @return the opcode selected for this instruction, or -1 if we don't know it + * yet + */ + public final short getOpcode() { + return opcode; + } + + /** + * Computes the type of data pushed onto the stack, or null if none is pushed. + * + * @param poppedTypesToCheck + * the types of the data popped off the stack by this instruction; if + * poppedTypes is null, then we don't know the incoming stack types + * and the result of this method may be less accurate + */ + public String getPushedType(String[] poppedTypesToCheck) { + return null; + } + + /** + * @return the JVM word size of the value this instruction pushes onto the + * stack, or 0 if this instruction doesn't push anything onto the + * stack. + */ + public byte getPushedWordSize() { + return 0; + } + + /** + * Apply a Visitor to this instruction. We invoke the appropriate Visitor + * method according to the type of this instruction. + */ + public abstract void visit(Visitor v); + + /** + * Subclasses must implement toString. + */ + public abstract String toString(); + + /** + * We're immutable so there's no need to clone any Instruction object. + */ + final public Object clone() { + return this; + } + + /** + * This class is used by Instruction.visit to dispatch based on the + * instruction type. + */ + public static abstract class Visitor { + public void visitConstant(ConstantInstruction instruction) { + } + + public void visitGoto(GotoInstruction instruction) { + } + + public void visitLocalLoad(LoadInstruction instruction) { + } + + public void visitLocalStore(StoreInstruction instruction) { + } + + public void visitArrayLoad(ArrayLoadInstruction instruction) { + } + + public void visitArrayStore(ArrayStoreInstruction instruction) { + } + + public void visitPop(PopInstruction instruction) { + } + + public void visitDup(DupInstruction instruction) { + } + + public void visitSwap(SwapInstruction instruction) { + } + + public void visitBinaryOp(BinaryOpInstruction instruction) { + } + + public void visitUnaryOp(UnaryOpInstruction instruction) { + } + + public void visitShift(ShiftInstruction instruction) { + } + + public void visitConversion(ConversionInstruction instruction) { + } + + public void visitComparison(ComparisonInstruction instruction) { + } + + public void visitConditionalBranch(ConditionalBranchInstruction instruction) { + } + + public void visitSwitch(SwitchInstruction instruction) { + } + + public void visitReturn(ReturnInstruction instruction) { + } + + public void visitGet(GetInstruction instruction) { + } + + public void visitPut(PutInstruction instruction) { + } + + public void visitInvoke(InvokeInstruction instruction) { + } + + public void visitNew(NewInstruction instruction) { + } + + public void visitArrayLength(ArrayLengthInstruction instruction) { + } + + public void visitThrow(ThrowInstruction instruction) { + } + + public void visitMonitor(MonitorInstruction instruction) { + } + + public void visitCheckCast(CheckCastInstruction instruction) { + } + + public void visitInstanceof(InstanceofInstruction instruction) { + } + } +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/InvokeInstruction.java b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/InvokeInstruction.java new file mode 100644 index 000000000..bba249834 --- /dev/null +++ b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/InvokeInstruction.java @@ -0,0 +1,192 @@ +/******************************************************************************* + * 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.shrikeBT; + +/** + * This class represents method invocation instructions. + */ +public class InvokeInstruction extends Instruction implements IInvokeInstruction { + protected String type; + protected String classType; + protected String methodName; + + InvokeInstruction(short opcode, String type, String classType, String methodName) { + this.type = type; + this.classType = classType; + this.methodName = methodName; + this.opcode = opcode; + } + + public static InvokeInstruction make(String type, String className, String methodName, Dispatch mode) { + if (type == null) { + throw new NullPointerException("type must not be null"); + } + if (className == null) { + throw new NullPointerException("className must not be null"); + } + if (methodName == null) { + throw new NullPointerException("methodName must not be null"); + } + return new InvokeInstruction((short) (OP_invokevirtual + mode.ordinal()), type, className, methodName); + } + + ConstantPoolReader getLazyConstantPool() { + return null; + } + + final static class Lazy extends InvokeInstruction { + private ConstantPoolReader cp; + private int index; + + Lazy(short opcode, ConstantPoolReader cp, int index) { + super(opcode, null, null, null); + this.index = index; + this.cp = cp; + } + + ConstantPoolReader getLazyConstantPool() { + return cp; + } + + int getCPIndex() { + return index; + } + + public String getClassType() { + if (classType == null) { + classType = cp.getConstantPoolMemberClassType(index); + } + return classType; + } + + public String getMethodName() { + if (methodName == null) { + methodName = cp.getConstantPoolMemberName(index); + } + return methodName; + } + + public String getMethodSignature() { + if (type == null) { + type = cp.getConstantPoolMemberType(index); + } + return type; + } + } + + static InvokeInstruction make(ConstantPoolReader cp, int index, int mode) { + if (mode < OP_invokevirtual || mode > OP_invokeinterface) { + throw new IllegalArgumentException("Unknown mode: " + mode); + } + return new Lazy((short) mode, cp, index); + } + + final public boolean equals(Object o) { + if (o instanceof InvokeInstruction) { + InvokeInstruction i = (InvokeInstruction) o; + return i.getMethodSignature().equals(getMethodSignature()) && i.getClassType().equals(getClassType()) + && i.getMethodName().equals(getMethodName()) && i.opcode == opcode; + } else { + return false; + } + } + + public String getClassType() { + return classType; + } + + public String getMethodName() { + return methodName; + } + + public String getMethodSignature() { + return type; + } + + final public int getInvocationMode() { + return opcode; + } + + final public String getInvocationModeString() { + switch (opcode) { + case Constants.OP_invokestatic: + return "STATIC"; + case Constants.OP_invokeinterface: + return "INTERFACE"; + case Constants.OP_invokespecial: + return "SPECIAL"; + case Constants.OP_invokevirtual: + return "VIRTUAL"; + default: + throw new Error("Unknown mode: " + opcode); + } + } + + final public int hashCode() { + return getMethodSignature().hashCode() + 9011 * getClassType().hashCode() + 317 * getMethodName().hashCode() + opcode * 3188; + } + + final public int getPoppedCount() { + return (opcode == Constants.OP_invokestatic ? 0 : 1) + Util.getParamsCount(getMethodSignature()); + } + + final public String getPushedType(String[] types) { + String t = Util.getReturnType(getMethodSignature()); + if (t.equals(Constants.TYPE_void)) { + return null; + } else { + return t; + } + } + + final public byte getPushedWordSize() { + String t = getMethodSignature(); + int index = t.lastIndexOf(')'); + return Util.getWordSize(t, index + 1); + } + + final public void visit(Visitor v) { + v.visitInvoke(this); + } + + final public String toString() { + return "Invoke(" + getInvocationModeString() + "," + getClassType() + "," + getMethodName() + "," + getMethodSignature() + ")"; + } + + /* + * (non-Javadoc) + * + * @see com.ibm.domo.cfg.IInstruction#isPEI() + */ + public boolean isPEI() { + return true; + } + + /* + * (non-Javadoc) + * + * @see com.ibm.domo.cfg.IInvokeInstruction#getInvocationCode() + */ + public Dispatch getInvocationCode() { + switch (opcode) { + case Constants.OP_invokestatic: + return Dispatch.STATIC; + case Constants.OP_invokeinterface: + return Dispatch.INTERFACE; + case Constants.OP_invokespecial: + return Dispatch.SPECIAL; + case Constants.OP_invokevirtual: + return Dispatch.VIRTUAL; + default: + throw new Error("Unknown mode: " + opcode); + } + } +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/LoadInstruction.java b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/LoadInstruction.java new file mode 100644 index 000000000..44a2b16aa --- /dev/null +++ b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/LoadInstruction.java @@ -0,0 +1,100 @@ +/******************************************************************************* + * 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.shrikeBT; + +/** + * This class represents local variable load instructions. + */ +public final class LoadInstruction extends Instruction { + private int index; + + protected LoadInstruction(short opcode, int index) { + this.index = index; + this.opcode = opcode; + } + + private final static LoadInstruction[] preallocated = preallocate(); + + private static LoadInstruction[] preallocate() { + LoadInstruction[] r = new LoadInstruction[5 * 16]; + for (int p = 0; p < 5; p++) { + for (int i = 0; i < 4; i++) { + r[p * 16 + i] = new LoadInstruction((short) (OP_iload_0 + i + p * 4), i); + } + for (int i = 4; i < 16; i++) { + r[p * 16 + i] = new LoadInstruction((short) (OP_iload + p), i); + } + } + return r; + } + + public static LoadInstruction make(String type, int index) { + int t = Util.getTypeIndex(type); + if (t < 0 || t > TYPE_Object_index) { + throw new IllegalArgumentException("Cannot load local of type " + type); + } + if (index < 16) { + return preallocated[t * 16 + index]; + } else { + return new LoadInstruction((short) (OP_iload + t), index); + } + } + + /** + * @return the index of the local variable loaded + */ + public int getVarIndex() { + return index; + } + + public String getType() { + if (opcode < OP_iload_0) { + return indexedTypes[opcode - OP_iload]; + } else { + return indexedTypes[(opcode - OP_iload_0) / 4]; + } + } + + public String getPushedType(String[] types) { + return getType(); + } + + public byte getPushedWordSize() { + return Util.getWordSize(getType()); + } + + public void visit(Visitor v) { + v.visitLocalLoad(this); + } + + public boolean equals(Object o) { + if (o instanceof LoadInstruction) { + LoadInstruction i = (LoadInstruction) o; + return i.index == index && i.opcode == opcode; + } else { + return false; + } + } + + public int hashCode() { + return opcode + index * 19801901; + } + + public String toString() { + return "LocalLoad(" + getType() + "," + index + ")"; + } + /* (non-Javadoc) + * @see com.ibm.domo.cfg.IInstruction#isPEI() + */ + public boolean isPEI() { + return false; + } +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/MethodData.java b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/MethodData.java new file mode 100644 index 000000000..e51fa128c --- /dev/null +++ b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/MethodData.java @@ -0,0 +1,243 @@ +/******************************************************************************* + * 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.shrikeBT; + +import java.util.HashMap; +import java.util.Iterator; + +/** + * This class is a container for a bunch of information that we might know about + * a method. It's here for convenience so users can just pass one MethodData + * around instead of passing around an array of instructions, an array of + * exception handler lists, etc. + * + * It also provides a place to hang annotations. We provide a table mapping + * abstract "keys" to annotation objects. We also provide an invalidation + * protocol so that the annotation objects can be notified of code changes and + * react appropriately. This is useful for caching analysis results for a + * method. + */ +public final class MethodData { + private HashMap map = new HashMap(); + + private int access; + private String classType; + private String name; + private String signature; + private Instruction[] instructions; + private ExceptionHandler[][] handlers; + private int[] instructionsToBytecodes; + private boolean hasChanged = false; + + /** + * Gather the information for a method "from scratch". + * + * @param access + * the access flags + * @param classType + * the class in which the method is defined, in JVM type format + * (e.g., Ljava/lang/Object;) + * @param name + * the method name + * @param signature + * the method signature, in JVM type format (e.g., + * (ILjava/lang/Object;)V) + * @param instructions + * the instructions making up the method + * @param handlers + * a list of exception handlers for each instruction + * @param instructionsToBytecodes + * a map stating, for each instruction, the offset of the original + * bytecode instruction(s) giving rise to this instruction + */ + public MethodData(int access, String classType, String name, String signature, Instruction[] instructions, + ExceptionHandler[][] handlers, int[] instructionsToBytecodes) { + this.classType = classType; + this.access = access; + this.name = name; + this.signature = signature; + this.instructions = instructions; + this.handlers = handlers; + this.instructionsToBytecodes = instructionsToBytecodes; + + if (instructions == null) { + throw new NullPointerException("Instruction array cannot be null"); + } + if (handlers == null) { + throw new NullPointerException("Handler array cannot be null"); + } + if (instructionsToBytecodes == null) { + throw new NullPointerException("InstructionToBytecodes array cannot be null"); + } + if (instructions.length != handlers.length) { + throw new IllegalArgumentException("Handlers array must be the same length as the instructions"); + } + if (instructions.length != instructionsToBytecodes.length) { + throw new IllegalArgumentException("Bytecode map array must be the same length as the instructions"); + } + } + + /** + * Gather the information for a method after it has been decoded. + * + * @param d + * the decoder which has decoded the method + * @param access + * the access flags + * @param classType + * the class in which the method is defined, in JVM type format + * (e.g., Ljava/lang/Object;) + * @param name + * the method name + * @param signature + * the method signature, in JVM type format (e.g., + * (ILjava/lang/Object;)V) + */ + public MethodData(Decoder d, int access, String classType, String name, String signature) { + this(access, classType, name, signature, d.getInstructions(), d.getHandlers(), d.getInstructionsToBytecodes()); + } + + public void setHasChanged() { + hasChanged = true; + } + + /** + * @return the method signature, in JVM format + */ + public String getSignature() { + return signature; + } + + /** + * @return the method name + */ + public String getName() { + return name; + } + + /** + * Xiangyu, + * + * @return the method access + */ + public int getAccess() { + return access; + } + + /** + * @return the JVM type for the class defining the method (e.g., + * Ljava/lang/Object;) + */ + public String getClassType() { + return classType; + } + + /** + * @return whether or not the method is static + */ + public boolean getIsStatic() { + return (access & Constants.ACC_STATIC) != 0; + } + + /** + * @return whether or not the method is synchronized + */ + public boolean getIsSynchronized() { + return (access & Constants.ACC_SYNCHRONIZED) != 0; + } + + /** + * @return the exception handler lists + */ + public ExceptionHandler[][] getHandlers() { + return handlers; + } + + /** + * @return the instruction array + */ + public Instruction[] getInstructions() { + return instructions; + } + + /** + * @return the map from instructions to bytecode offsets + */ + public int[] getInstructionsToBytecodes() { + return instructionsToBytecodes; + } + + /** + * Annotation objects implement this Results interface. The Results interface + * is used to notify an annotation that the method code has been updated. + */ + public static interface Results { + /** + * This method is called just before the code for a method changes. The + * existing instructions, handlers, etc can be read from the current info. + * + * @param info + * the method data this annotation is attached to + * @param newInstructions + * the instructions the method will change to + * @param newHandlers + * the handler lists the method will change to + * @param newInstructionMap + * the instructions-to-bytecodes map the method will change to + * @return true to remove the object from the info set, for example because + * the annotation is now invalid + */ + public boolean notifyUpdate(MethodData info, Instruction[] newInstructions, ExceptionHandler[][] newHandlers, + int[] newInstructionMap); + } + + /** + * Get the annotation for the given key. + * + * @return the annotation or null if there isn't one + */ + public Results getInfo(Object key) { + return map.get(key); + } + + /** + * Set the annotation for the given key. + */ + public void putInfo(Object key, Results value) { + map.put(key, value); + } + + void update(Instruction[] instructions, ExceptionHandler[][] handlers, int[] newInstructionMap, int[] instructionsToBytecodes) { + for (Iterator i = map.keySet().iterator(); i.hasNext();) { + Object key = i.next(); + Results r = map.get(key); + if (r.notifyUpdate(this, instructions, handlers, newInstructionMap)) { + i.remove(); + } + } + + this.instructions = instructions; + this.handlers = handlers; + this.instructionsToBytecodes = instructionsToBytecodes; + hasChanged = true; + } + + /** + * @return true iff the code has been updated at least once + */ + public boolean getHasChanged() { + return hasChanged; + } + + public String toString() { + return getClassType() + "." + getName() + getSignature(); + } +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/MethodEditor.java b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/MethodEditor.java new file mode 100644 index 000000000..b40924c2f --- /dev/null +++ b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/MethodEditor.java @@ -0,0 +1,707 @@ +/******************************************************************************* + * 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.shrikeBT; + +import java.util.ArrayList; +import java.util.HashSet; + +/** + * The MethodEditor is the core of the ShrikeBT code rewriting mechanism. To + * rewrite code, construct a MethodEditor initialized with the intial code for + * the method. Then perform a series of passes. In each pass you call + * beginPass(), insert a number of patches using the insert...() or replace...() + * methods, then optionally call applyPatches() to update the code with your + * changes, then call endPass(). The end of each pass updates the code in the + * MethodData that you passed in, so the new code can be extracted from that + * MethodData object. Note that if applyPatches() is not called, or it is called + * but no patches had been inserted, then the code will not be updated and that + * pass is essentially aborted. + * + * A patch is simply a subclass of MethodEditor.Patch, representing a code + * sequence to insert into the method. Each patch class implements one method, + * emitTo(), which writes the patch code into the code stream using the provided + * MethodEditor.Output instance. Anonymous inner classes are very useful for + * writing patches. + * + * Patches can be inserted at the following points: + *
                                + *
                              • Before the start of the method + *
                              • Before or after a particular instruction + *
                              • Replacing a particular instruction + *
                              • Handling an exception on a particular instruction + *
                              • Handling an exception anywhere in the method + *
                              • After the end of the method, where code will not normally be executed, + * but can be branched to by another patch + *
                              + * Patch application is deterministic; if two patches are applied at the same + * point, then the order of application determines the order of code generation, + * in a way specified by the particular application point. See the patch + * application methods below. + * + * MethodEditor relies on labels. A label is an integer representing a point in + * the code. Labels are valid only during a single pass; at the end of each + * pass, instructions are reordered and old labels become invalid. At the + * beginning of a pass every instruction in the instructions array is labelled + * with the index of that instruction in the array. During instrumentation new + * labels can be allocated by calling MethodEditor.allocateLabel(); control + * instructions can be created referring to these new labels or the existing + * labels. At the end of a pass, as patch code is spliced into the method body, + * all instructions are updated to refer to the new labels which are simply the + * indices of instructions in the instruction array. + */ +public final class MethodEditor { + private static final ExceptionHandler[] noHandlers = new ExceptionHandler[0]; + + /** Records which original bytecode instruction each Instruction belongs to. */ + private int[] instructionsToBytecodes; + private Instruction[] instructions; + private ExceptionHandler[][] handlers; + + private MethodData methodInfo; + + // working + private static final int BEFORE_PASS = 0x01; + private static final int DURING_PASS = 0x02; + private static final int EMITTING_CODE = 0x04; + private static final int BEFORE_END_PASS = 0x08; + + private int state = BEFORE_PASS; + private int patchCount; + private Patch[] beforePatches; + private Patch[] afterPatches; + private Patch[] lastAfterPatches; + private Patch[] replacementPatches; + private Patch methodStartPatches; + private Patch afterMethodPatches; + private HandlerPatch[] instructionHandlerPatches; + private HandlerPatch methodHandlerPatches; + private int nextLabel; + + /** + * This patch lets us stuff an exception handler into the code. + */ + private static class HandlerPatch { + HandlerPatch next; + String catchClass; + int label; + Patch patch; + + HandlerPatch(HandlerPatch next, String catchClass, int label, Patch patch) { + this.next = next; + this.catchClass = catchClass; + this.label = label; + this.patch = patch; + } + } + + /** + * Build an editor for the given method. This editor will write back its + * changes to the method info. + */ + public MethodEditor(MethodData info) { + methodInfo = info; + instructionsToBytecodes = info.getInstructionsToBytecodes(); + instructions = info.getInstructions(); + handlers = info.getHandlers(); + } + + /** + * Build an editor for specific method data. After patching the code you can + * retrieve the new code, handlers and instructions-to-bytecode-offsets map. + */ + public MethodEditor(Instruction[] instructions, ExceptionHandler[][] handlers, int[] instructionsToBytecodes) { + methodInfo = null; + this.instructionsToBytecodes = instructionsToBytecodes; + this.instructions = instructions; + this.handlers = handlers; + } + + private void verifyState(int state) { + if ((state & this.state) == 0) { + throw new IllegalArgumentException(getStateMessage(state)); + } + } + + private String getStateMessage(int state) { + switch (state) { + case BEFORE_PASS: + return "This operation can only be performed before or after an editing pass"; + case DURING_PASS: + return "This operation can only be performed during an editing pass"; + case EMITTING_CODE: + return "This operation can only be performed while applying patches and emitting code"; + case BEFORE_END_PASS: + return "This operation can only be performed after applying patches"; + default: + return "This operation cannot be performed in this state"; + } + } + + /** + * @return the current handler array + */ + public ExceptionHandler[][] getHandlers() { + verifyState(BEFORE_PASS | DURING_PASS); + return handlers; + } + + /** + * @return the current instruction array + */ + public Instruction[] getInstructions() { + verifyState(BEFORE_PASS | DURING_PASS); + return instructions; + } + + /** + * @return the current instructions-to-bytecode-offsets map + */ + public int[] getInstructionsToBytecodes() { + verifyState(BEFORE_PASS | DURING_PASS); + return instructionsToBytecodes; + } + + static ExceptionHandler[] mergeHandlers(ExceptionHandler[] h1, ExceptionHandler[] h2) { + if (h1.length == 0) { + return h2; + } else if (h2.length == 0) { + return h1; + } else { + ExceptionHandler[] r = new ExceptionHandler[h1.length + h2.length]; + System.arraycopy(h1, 0, r, 0, h1.length); + System.arraycopy(h2, 0, r, h1.length, h2.length); + return r; + } + } + + /** + * Output is the interface that patches use to emit their code into a method + * body. + */ + public final static class Output { + ArrayList newInstructions = new ArrayList(); + ArrayList newInstructionHandlers = new ArrayList(); + int[] instructionsToBytecodes = new int[10]; + int[] labelDefs; + ExceptionHandler[] additionalHandlers; + int originalBytecode; + boolean codeChanged = false; + + Output(int numLabels) { + labelDefs = new int[numLabels]; + } + + /** + * Emit a label definition at the current point in the code. The label must + * have been previously allocated using MethodEditor.allocateLabel. + */ + public void emitLabel(int label) { + labelDefs[label] = newInstructions.size(); + } + + /** + * Emit an instruction at the current point in the code. + */ + public void emit(Instruction i) { + codeChanged = true; + internalEmitInstruction(i); + } + + /** + * Emit an instruction with some exception handlers at the current point in + * the code. + */ + public void emit(Instruction i, ExceptionHandler[] handlers) { + codeChanged = true; + + int s = newInstructions.size(); + if (s + 1 > instructionsToBytecodes.length) { + int[] t = new int[instructionsToBytecodes.length * 2]; + System.arraycopy(instructionsToBytecodes, 0, t, 0, instructionsToBytecodes.length); + instructionsToBytecodes = t; + } + + instructionsToBytecodes[s] = originalBytecode; + newInstructions.add(i); + newInstructionHandlers.add(mergeHandlers(handlers, additionalHandlers)); + } + + void internalEmitInstruction(Instruction i) { + int s = newInstructions.size(); + if (s + 1 > instructionsToBytecodes.length) { + int[] t = new int[instructionsToBytecodes.length * 2]; + System.arraycopy(instructionsToBytecodes, 0, t, 0, instructionsToBytecodes.length); + instructionsToBytecodes = t; + } + + instructionsToBytecodes[s] = originalBytecode; + newInstructions.add(i); + newInstructionHandlers.add(additionalHandlers); + } + + /** + * Emit a list of instructions at the current point in the code. + */ + public void emit(Instruction[] instrs) { + emit(instrs, noHandlers); + } + + /** + * Emit a list of instructions with some exception handlers at the current + * point in the code. All the instructions are covered by all the handlers. + */ + public void emit(Instruction[] instrs, ExceptionHandler[] handlers) { + if (instrs.length == 0) { + return; + } + codeChanged = true; + + int s = newInstructions.size(); + if (s + instrs.length > instructionsToBytecodes.length) { + int[] t = new int[instructionsToBytecodes.length * 2 + instrs.length]; + System.arraycopy(instructionsToBytecodes, 0, t, 0, instructionsToBytecodes.length); + instructionsToBytecodes = t; + } + + ExceptionHandler[] hs = mergeHandlers(handlers, additionalHandlers); + for (int i = 0; i < instrs.length; i++) { + instructionsToBytecodes[s + i] = originalBytecode; + newInstructions.add(instrs[i]); + newInstructionHandlers.add(hs); + } + } + } + + /** + * This class is subclassed for each kind of patch that you want to apply. + */ + public static abstract class Patch { + Patch next; + + public Patch() { + } + + final Patch insert(Patch next) { + this.next = next; + return this; + } + + /** + * Override this method to emit the code for your patch. + */ + public abstract void emitTo(Output w); + } + + /** + * This must be called before inserting any patches. + */ + public void beginPass() { + verifyState(BEFORE_PASS); + state = DURING_PASS; + + nextLabel = instructions.length; + beforePatches = new Patch[instructions.length]; + afterPatches = new Patch[instructions.length]; + lastAfterPatches = new Patch[instructions.length]; + replacementPatches = new Patch[instructions.length]; + instructionHandlerPatches = new HandlerPatch[instructions.length]; + methodStartPatches = null; + afterMethodPatches = null; + methodHandlerPatches = null; + patchCount = 0; + } + + /** + * This must be called after inserting any patches. + */ + public void endPass() { + state = BEFORE_PASS; + + // lose references to the stored patches so they can be garbage collected + beforePatches = null; + afterPatches = null; + lastAfterPatches = null; + replacementPatches = null; + instructionHandlerPatches = null; + methodStartPatches = null; + afterMethodPatches = null; + methodHandlerPatches = null; + } + + /** + * Allocate a fresh label. This must be called during a pass and not during + * code emission. + */ + public int allocateLabel() { + verifyState(DURING_PASS); + return nextLabel++; + } + + /** + * Insert code to be executed whenever the method is entered. This code is not + * protected by any exception handlers (other than handlers declared in the + * patch). + * + * When multiple 'start' patches are given, the last one added is first in + * execution order. + */ + public void insertAtStart(Patch p) { + verifyState(DURING_PASS); + methodStartPatches = p.insert(methodStartPatches); + patchCount++; + } + + /** + * Insert code to be executed before the instruction. Branches to the + * instruction will branch to this code. Exception handlers that cover the + * instruction will be extended to cover the patch. + * + * When multiple 'before' patches are given, the last one added is first in + * execution order. + */ + public void insertBefore(int i, Patch p) { + verifyState(DURING_PASS); + beforePatches[i] = p.insert(beforePatches[i]); + patchCount++; + } + + /** + * Insert code to be executed after the instruction. This code will only + * execute if the instruction "falls through". For example, code inserted + * after a "goto" will never be executed. Likewise if the instruction throws + * an execution the 'after' code will not be executed. Exception handlers that + * cover the instruction will be extended to cover the patch. + * + * When multiple 'after' patches are given, the last one added is LAST in + * execution order. + */ + public void insertAfter(int i, Patch p) { + verifyState(DURING_PASS); + if (afterPatches[i] == null) { + lastAfterPatches[i] = afterPatches[i] = p.insert(null); + } else { + lastAfterPatches[i].next = p; + lastAfterPatches[i] = p.insert(null); + } + patchCount++; + } + + /** + * Insert code to replace the instruction. Exception handlers that cover the + * instruction will cover the patch. + * + * Multiple replacements are not allowed. + */ + public void replaceWith(int i, Patch p) { + verifyState(DURING_PASS); + if (replacementPatches[i] != null) { + throw new IllegalArgumentException("Instruction " + i + " cannot be replaced more than once"); + } + replacementPatches[i] = p.insert(null); + patchCount++; + } + + /** + * An "instruction exception handler" handles exceptions generated by a + * specific instruction (including patch code that may be inserted before, + * after, or instead of the instruction in this pass). If the patch code falls + * through, control resumes with the next instruction. This exception handler + * handles exceptions before any exception handler already attached to the + * instruction. Furthermore, the patch itself is covered by the exception + * handlers already attached to the instruction. + * + * If multiple instruction exception handlers are given, then the last one + * added handles the exception first; if an exception is rethrown, then the + * next-to-last one added handles that exception, etc. + */ + public void addInstructionExceptionHandler(int i, String catchClass, Patch p) { + verifyState(DURING_PASS); + instructionHandlerPatches[i] = new HandlerPatch(instructionHandlerPatches[i], catchClass, allocateLabel(), p); + patchCount++; + } + + /** + * A "method exception handler" handles exceptions generated anywhere in the + * method. The patch code must not fall through; it must return or throw an + * exception. + * + * If multiple method exception handlers are given, then the last one added + * handles the exception first; if an exception is rethrown, then the + * next-to-last one added handles that exception, etc. + */ + public void addMethodExceptionHandler(String catchClass, Patch p) { + verifyState(DURING_PASS); + methodHandlerPatches = new HandlerPatch(methodHandlerPatches, catchClass, allocateLabel(), p); + patchCount++; + } + + /** + * This method inserts code that will be placed after the method body. This + * code will not be executed normally, but it can emit label definitions that + * other patches can branch to. No exception handlers cover this code (other + * than exception handlers emitted by patch p itself). + */ + public void insertAfterBody(Patch p) { + verifyState(DURING_PASS); + afterMethodPatches = p.insert(afterMethodPatches); + patchCount++; + } + + /** + * @return the MethodData used to create this editor, or null if no MethodData + * is linked to this editor + */ + public MethodData getData() { + return methodInfo; + } + + private static ExceptionHandler[] makeExceptionArray(HandlerPatch hp) { + if (hp == null) { + return noHandlers; + } else { + int count = 0; + for (HandlerPatch hpIterator = hp; hpIterator != null; hpIterator = hpIterator.next) { + count++; + } + + ExceptionHandler[] patchedHandlers = new ExceptionHandler[count]; + count = 0; + for (HandlerPatch hpIterator = hp; hpIterator != null; hpIterator = hpIterator.next) { + patchedHandlers[count] = new ExceptionHandler(hpIterator.label, hpIterator.catchClass); + count++; + } + + return patchedHandlers; + } + } + + /** + * This method finishes a pass. All code is updated; instructions are + * reordered and old labels may not be valid. + * + * If no patches were issued, we don't need to do anything at all; this case + * is detected quickly and no updates are made. + * + * @return true iff non-trivial patches were applied + */ + public boolean applyPatches() { + verifyState(DURING_PASS); + state = EMITTING_CODE; + + if (patchCount == 0) { + state = BEFORE_END_PASS; + // no patches issued; drop out + return false; + } + + Output w = new Output(nextLabel); + + int[] oldInstructionsToNew = new int[instructions.length]; + + w.additionalHandlers = noHandlers; + w.originalBytecode = 0; + for (Patch p = methodStartPatches; p != null; p = p.next) { + p.emitTo(w); + } + + ExceptionHandler[] methodHandlers = makeExceptionArray(methodHandlerPatches); + if (methodHandlers.length > 0) { + // if a method handler is added, the code has changed even though + // the patch might not emit any actual code + w.codeChanged = true; + } + + for (int i = 0; i < instructions.length; i++) { + ExceptionHandler[] basicHandlers = mergeHandlers(handlers[i], methodHandlers); + HandlerPatch hp = instructionHandlerPatches[i]; + + w.emitLabel(i); + w.originalBytecode = instructionsToBytecodes[i]; + + w.additionalHandlers = basicHandlers; + for (Patch p = beforePatches[i]; p != null; p = p.next) { + p.emitTo(w); + } + + w.additionalHandlers = mergeHandlers(makeExceptionArray(hp), basicHandlers); + Patch replace = replacementPatches[i]; + if (replace == null) { + oldInstructionsToNew[i] = w.newInstructions.size(); + w.internalEmitInstruction(instructions[i]); + } else { + // a patch might delete an instruction, in which case the + // code is definitely modified + w.codeChanged = true; + oldInstructionsToNew[i] = -1; + replace.emitTo(w); + } + + w.additionalHandlers = basicHandlers; + for (Patch p = afterPatches[i]; p != null; p = p.next) { + p.emitTo(w); + } + + if (hp != null) { + // if an instruction handler is added, the code has changed even though + // the patch might not emit any actual code + w.codeChanged = true; + + GotoInstruction branchOver = GotoInstruction.make(i + 1); + + w.internalEmitInstruction(branchOver); + for (HandlerPatch hpIterator = hp; hpIterator != null; hpIterator = hpIterator.next) { + w.additionalHandlers = mergeHandlers(makeExceptionArray(hpIterator.next), basicHandlers); + w.emitLabel(hpIterator.label); + hpIterator.patch.emitTo(w); + w.internalEmitInstruction(branchOver); + } + } + } + + w.originalBytecode = 0; + + for (HandlerPatch hpIterator = methodHandlerPatches; hpIterator != null; hpIterator = hpIterator.next) { + w.additionalHandlers = makeExceptionArray(hpIterator.next); + w.emitLabel(hpIterator.label); + hpIterator.patch.emitTo(w); + } + + w.additionalHandlers = noHandlers; + for (Patch p = afterMethodPatches; p != null; p = p.next) { + p.emitTo(w); + } + + state = BEFORE_END_PASS; + + if (!w.codeChanged) { + return false; + } + + instructions = new Instruction[w.newInstructions.size()]; + handlers = new ExceptionHandler[instructions.length][]; + instructionsToBytecodes = new int[instructions.length]; + + w.newInstructions.toArray(instructions); + w.newInstructionHandlers.toArray(handlers); + System.arraycopy(w.instructionsToBytecodes, 0, instructionsToBytecodes, 0, instructionsToBytecodes.length); + + int[] labelDefs = w.labelDefs; + + int[] newInstructionsToOld = new int[instructions.length]; + + for (int i = 0; i < instructions.length; i++) { + instructions[i] = instructions[i].redirectTargets(labelDefs); + newInstructionsToOld[i] = -1; + } + + // We want to update each exception handler array exactly once + HashSet adjustedHandlers = null; + for (int i = 0; i < handlers.length; i++) { + ExceptionHandler[] hs = handlers[i]; + if (hs.length > 0 && (i == 0 || hs != handlers[i - 1])) { + if (adjustedHandlers == null) { + adjustedHandlers = new HashSet(); + } + + for (int j = 0; j < hs.length; j++) { + ExceptionHandler h = hs[j]; + if (!adjustedHandlers.contains(h)) { + adjustedHandlers.add(h); + h.handler = labelDefs[h.handler]; + } + } + } + } + + if (methodInfo != null) { + for (int i = 0; i < oldInstructionsToNew.length; i++) { + if (oldInstructionsToNew[i] != -1) { + newInstructionsToOld[oldInstructionsToNew[i]] = i; + } + } + methodInfo.update(instructions, handlers, newInstructionsToOld, instructionsToBytecodes); + } + + return true; + } + + /** + * Apply Visitor v to each instruction in the code, for the purpose of + * patching the code. + */ + public void visitInstructions(Visitor v) { + verifyState(DURING_PASS); + + for (int i = 0; i < instructions.length; i++) { + v.setIndex(this, i); + instructions[i].visit(v); + } + } + + /** + * A specialized Instruction.Visitor providing convenience methods for + * inserting patches. In particular it maintains a notion of the "current + * position" in the code array. + */ + public static class Visitor extends Instruction.Visitor { + private int index; + private MethodEditor editor; + + /** + * Set the current editor and instruction index for this visitor. + */ + final public void setIndex(MethodEditor e, int i) { + index = i; + editor = e; + } + + /** + * @return the index of the current instruction in the code array + */ + final public int getIndex() { + return index; + } + + /** + * Insert a patch after the current instruction in the code. + */ + final public void insertAfter(Patch p) { + editor.insertAfter(index, p); + } + + /** + * Insert a patch before the current instruction in the code. + */ + final public void insertBefore(Patch p) { + editor.insertBefore(index, p); + } + + /** + * Replace the current instruction in the code with a patch. + */ + final public void replaceWith(Patch p) { + editor.replaceWith(index, p); + } + + /** + * Add an exception handler to the current instruction. + * + * @param catchClass + * the JVM type for the exception to be caught (e.g., + * Ljava.io.IOException;), or null to catch all exceptions + * @param p + * the code to handle the exception + */ + final public void addInstructionExceptionHandler(String catchClass, Patch p) { + editor.addInstructionExceptionHandler(index, catchClass, p); + } + } +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/MonitorInstruction.java b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/MonitorInstruction.java new file mode 100644 index 000000000..a6b1e0a06 --- /dev/null +++ b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/MonitorInstruction.java @@ -0,0 +1,62 @@ +/******************************************************************************* + * 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.shrikeBT; + +/** + * This class represents monitorenter and monitorexit instructions. + */ +public final class MonitorInstruction extends Instruction { + protected MonitorInstruction(short opcode) { + this.opcode = opcode; + } + + private final static MonitorInstruction enter = new MonitorInstruction(OP_monitorenter); + private final static MonitorInstruction exit = new MonitorInstruction(OP_monitorexit); + + public static MonitorInstruction make(boolean entering) { + return entering ? enter : exit; + } + + public boolean equals(Object o) { + if (o instanceof MonitorInstruction) { + MonitorInstruction i = (MonitorInstruction) o; + return i.opcode == opcode; + } else { + return false; + } + } + + public boolean isEnter() { + return opcode == OP_monitorenter; + } + + public int hashCode() { + return opcode + 1911; + } + + public int getPoppedCount() { + return 1; + } + + public void visit(Visitor v) { + v.visitMonitor(this); + } + + public String toString() { + return "Monitor(" + (isEnter() ? "ENTER" : "EXIT") + ")"; + } + /* (non-Javadoc) + * @see com.ibm.domo.cfg.IInstruction#isPEI() + */ + public boolean isPEI() { + return true; + } +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/NewInstruction.java b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/NewInstruction.java new file mode 100644 index 000000000..e94c5d482 --- /dev/null +++ b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/NewInstruction.java @@ -0,0 +1,109 @@ +/******************************************************************************* + * 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.shrikeBT; + +public final class NewInstruction extends Instruction { + private String type; + private short arrayBoundsCount; + + protected NewInstruction(short opcode, String type, short arrayBoundsCount) { + this.type = type; + this.arrayBoundsCount = arrayBoundsCount; + this.opcode = opcode; + } + + /** + * @param type + * the type of the object that will be returned (in JVM format, e.g., + * [Ljava/lang/String;) + * @param arrayBoundsCount + * the number of array dimensions to preconstruct (equal to the + * number of integer parameters this instruction expects) + */ + public static NewInstruction make(String type, int arrayBoundsCount) { + if (arrayBoundsCount < 0 || arrayBoundsCount > 255) { + throw new IllegalArgumentException("Too many array bounds: " + arrayBoundsCount); + } else { + if (type.length() < arrayBoundsCount + 1) { + throw new IllegalArgumentException("Not enough array nesting in " + type + " for bounds count " + arrayBoundsCount); + } + for (int i = 0; i < arrayBoundsCount; i++) { + if (type.charAt(i) != '[') { + throw new IllegalArgumentException("Not enough array nesting in " + type + " for bounds count " + arrayBoundsCount); + } + } + + short opcode; + + if (arrayBoundsCount == 0) { + opcode = OP_new; + } else if (arrayBoundsCount == 1) { + char ch = type.charAt(1); + if (ch != 'L' && ch != '[') { + // array of primitive type + opcode = OP_newarray; + } else { + opcode = OP_anewarray; + } + } else { + opcode = OP_multianewarray; + } + return new NewInstruction(opcode, type, (short) arrayBoundsCount); + } + } + + public boolean equals(Object o) { + if (o instanceof NewInstruction) { + NewInstruction i = (NewInstruction) o; + return i.type.equals(type) && i.arrayBoundsCount == arrayBoundsCount; + } else { + return false; + } + } + + public int getArrayBoundsCount() { + return arrayBoundsCount; + } + + public int hashCode() { + return 13111143 * type.hashCode() + arrayBoundsCount; + } + + public int getPoppedCount() { + return arrayBoundsCount; + } + + public String getPushedType(String[] types) { + return type; + } + + public byte getPushedWordSize() { + return 1; + } + + public String getType() { + return type; + } + + public String toString() { + return "New(" + type + "," + arrayBoundsCount + ")"; + } + + public void visit(Visitor v) { + v.visitNew(this); + } + /* (non-Javadoc) + * @see com.ibm.domo.cfg.IInstruction#isPEI() + */ + public boolean isPEI() { + return true; + } +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/PopInstruction.java b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/PopInstruction.java new file mode 100644 index 000000000..18b4e1aea --- /dev/null +++ b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/PopInstruction.java @@ -0,0 +1,65 @@ +/******************************************************************************* + * 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.shrikeBT; + +/** + * PopInstructions pop one or two elements off the working stack. + */ +public final class PopInstruction extends Instruction { + private byte size; + + protected PopInstruction(byte size) { + this.size = size; + } + + /** + * @param size + * 1 or 2, the number of elements to pop + */ + public static PopInstruction make(int size) { + if (size < 0 || size > 2) { + throw new IllegalArgumentException("Invalid pop size: " + size); + } else { + return new PopInstruction((byte) size); + } + } + + public boolean equals(Object o) { + if (o instanceof PopInstruction) { + PopInstruction i = (PopInstruction) o; + return i.size == size; + } else { + return false; + } + } + + public int hashCode() { + return size + 8431890; + } + + public int getPoppedCount() { + return size; + } + + public void visit(Visitor v) { + v.visitPop(this); + } + + public String toString() { + return "Pop(" + size + ")"; + } + /* (non-Javadoc) + * @see com.ibm.domo.cfg.IInstruction#isPEI() + */ + public boolean isPEI() { + return false; + } +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/PutInstruction.java b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/PutInstruction.java new file mode 100644 index 000000000..ce3ffab1a --- /dev/null +++ b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/PutInstruction.java @@ -0,0 +1,137 @@ +/******************************************************************************* + * 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.shrikeBT; + +/** + * This class represents put and putstatic instructions. + */ +public class PutInstruction extends Instruction { + protected String type; + protected String classType; + protected String fieldName; + + PutInstruction(short opcode, String type, String classType, String fieldName) { + this.type = type; + this.classType = classType; + this.fieldName = fieldName; + this.opcode = opcode; + } + + ConstantPoolReader getLazyConstantPool() { + return null; + } + + final static class Lazy extends PutInstruction { + private ConstantPoolReader cp; + private int index; + + Lazy(short opcode, ConstantPoolReader cp, int index) { + super(opcode, null, null, null); + this.index = index; + this.cp = cp; + } + + ConstantPoolReader getLazyConstantPool() { + return cp; + } + + int getCPIndex() { + return index; + } + + public String getClassType() { + if (classType == null) { + classType = cp.getConstantPoolMemberClassType(index); + } + return classType; + } + + public String getFieldName() { + if (fieldName == null) { + fieldName = cp.getConstantPoolMemberName(index); + } + return fieldName; + } + + public String getFieldType() { + if (type == null) { + type = cp.getConstantPoolMemberType(index); + } + return type; + } + } + + static PutInstruction make(ConstantPoolReader cp, int index, boolean isStatic) { + return new Lazy(isStatic ? OP_putstatic : OP_putfield, cp, index); + } + + public static PutInstruction make(String type, String className, String fieldName, boolean isStatic) { + if (type == null) { + throw new NullPointerException("type must not be null"); + } + if (className == null) { + throw new NullPointerException("className must not be null"); + } + if (fieldName == null) { + throw new NullPointerException("fieldName must not be null"); + } + return new PutInstruction(isStatic ? OP_putstatic : OP_putfield, type, className, fieldName); + } + + final public boolean equals(Object o) { + if (o instanceof PutInstruction) { + PutInstruction i = (PutInstruction) o; + return i.getFieldType().equals(getFieldType()) && i.getClassType().equals(getClassType()) + && i.getFieldName().equals(getFieldName()) && i.opcode == opcode; + } else { + return false; + } + } + + public String getClassType() { + return classType; + } + + public String getFieldType() { + return type; + } + + public String getFieldName() { + return fieldName; + } + + final public boolean isStatic() { + return opcode == OP_putstatic; + } + + final public int hashCode() { + return getClassType().hashCode() + 9011 * getClassType().hashCode() + 317 * getFieldName().hashCode() + opcode; + } + + final public int getPoppedCount() { + return isStatic() ? 1 : 2; + } + + final public String toString() { + return "Put(" + getFieldType() + "," + (isStatic() ? "STATIC" : "NONSTATIC") + "," + getClassType() + "," + getFieldName() + + ")"; + } + + final public void visit(Visitor v) { + v.visitPut(this); + } + /* (non-Javadoc) + * @see com.ibm.domo.cfg.IInstruction#isPEI() + */ + public boolean isPEI() { + return true; + } +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/ReturnInstruction.java b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/ReturnInstruction.java new file mode 100644 index 000000000..877d9ce49 --- /dev/null +++ b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/ReturnInstruction.java @@ -0,0 +1,82 @@ +/******************************************************************************* + * 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.shrikeBT; + +/** + * This instruction represents all return instructions. + */ +public final class ReturnInstruction extends Instruction { + protected ReturnInstruction(short opcode) { + this.opcode = opcode; + } + + private static final ReturnInstruction[] preallocated = preallocate(); + private static final ReturnInstruction preallocatedVoid = new ReturnInstruction(OP_return); + + private static ReturnInstruction[] preallocate() { + ReturnInstruction[] r = new ReturnInstruction[OP_areturn - OP_ireturn + 1]; + for (int i = 0; i < r.length; i++) { + r[i] = new ReturnInstruction((short) (OP_ireturn + i)); + } + return r; + } + + public static ReturnInstruction make(String type) { + if (type.equals(TYPE_void)) { + return preallocatedVoid; + } else { + int t = Util.getTypeIndex(type); + if (t < 0 || t > TYPE_Object_index) { + throw new IllegalArgumentException("Cannot return type " + type); + } + return preallocated[t]; + } + } + + public boolean equals(Object o) { + if (o instanceof ReturnInstruction) { + ReturnInstruction i = (ReturnInstruction) o; + return i.opcode == opcode; + } else { + return false; + } + } + + public boolean isFallThrough() { + return false; + } + + public int hashCode() { + return opcode + 31111; + } + + public int getPoppedCount() { + return opcode == OP_return ? 0 : 1; + } + + public String getType() { + return opcode == OP_return ? TYPE_void : indexedTypes[opcode - OP_ireturn]; + } + + public void visit(Visitor v) { + v.visitReturn(this); + } + + public String toString() { + return "Return(" + getType() + ")"; + } + /* (non-Javadoc) + * @see com.ibm.domo.cfg.IInstruction#isPEI() + */ + public boolean isPEI() { + return false; + } +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/Settings.java b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/Settings.java new file mode 100644 index 000000000..e3804f92e --- /dev/null +++ b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/Settings.java @@ -0,0 +1,25 @@ +/******************************************************************************* + * 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.shrikeBT; + +/** + * Settings for the whole ShrikeBT package. + */ +public class Settings { + /** + * Used to enable various checks if in DEBUG mode. + */ + public static final boolean DEBUG = false; + + public int hashCode() { + throw new Error("Settings.hashCode(): define a custom hash code to avoid non-determinancy"); + } +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/ShiftInstruction.java b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/ShiftInstruction.java new file mode 100644 index 000000000..42114b31c --- /dev/null +++ b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/ShiftInstruction.java @@ -0,0 +1,92 @@ +/******************************************************************************* + * 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.shrikeBT; + +/** + * ShiftInstructions are distinguished from BinaryOpInstructions because most + * binary operations in the JVM require both parameters to be the same type, but + * shifts always take one int parameter. + */ +public final class ShiftInstruction extends Instruction { + public enum Operator implements BinaryOpInstruction.IOperator { + SHL, SHR, USHR; + } + + protected ShiftInstruction(short opcode) { + this.opcode = opcode; + } + + private static final ShiftInstruction[] preallocated = preallocate(); + + private static ShiftInstruction[] preallocate() { + ShiftInstruction[] r = new ShiftInstruction[OP_lushr - OP_ishl + 1]; + for (int i = 0; i < r.length; i++) { + r[i] = new ShiftInstruction((short) (i + OP_ishl)); + } + return r; + } + + public static ShiftInstruction make(String type, Operator operator) { + int t = Util.getTypeIndex(type); + if (t < 0 || t > TYPE_long_index) { + throw new IllegalArgumentException("Cannot apply shift to type " + type); + } + + return preallocated[(operator.ordinal() - Operator.SHL.ordinal()) * 2 + t]; + } + + public boolean equals(Object o) { + if (o instanceof ShiftInstruction) { + ShiftInstruction i = (ShiftInstruction) o; + return i.opcode == opcode; + } else { + return false; + } + } + + public Operator getOperator() { + return Operator.values()[(opcode - OP_ishl) / 2]; + } + + public int hashCode() { + return opcode; + } + + public int getPoppedCount() { + return 2; + } + + public String getPushedType(String[] types) { + return getType(); + } + + public byte getPushedWordSize() { + return Util.getWordSize(getType()); + } + + public String getType() { + return indexedTypes[(opcode - OP_ishl) & 1]; + } + + public void visit(Visitor v) { + v.visitShift(this); + } + + public String toString() { + return "Shift(" + getType() + "," + getOperator() + ")"; + } + /* (non-Javadoc) + * @see com.ibm.domo.cfg.IInstruction#isPEI() + */ + public boolean isPEI() { + return false; + } +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/StoreInstruction.java b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/StoreInstruction.java new file mode 100644 index 000000000..58f5ab93b --- /dev/null +++ b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/StoreInstruction.java @@ -0,0 +1,96 @@ +/******************************************************************************* + * 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.shrikeBT; + +/** + * This class represents instructions that store to local variables. + */ +public final class StoreInstruction extends Instruction { + private int index; + + protected StoreInstruction(short opcode, int index) { + this.index = index; + this.opcode = opcode; + } + + private final static StoreInstruction[] preallocated = preallocate(); + + private static StoreInstruction[] preallocate() { + StoreInstruction[] r = new StoreInstruction[5 * 16]; + for (int p = 0; p < 5; p++) { + for (int i = 0; i < 4; i++) { + r[p * 16 + i] = new StoreInstruction((short) (OP_istore_0 + i + p * 4), i); + } + for (int i = 4; i < 16; i++) { + r[p * 16 + i] = new StoreInstruction((short) (OP_istore + p), i); + } + } + return r; + } + + public static StoreInstruction make(String type, int index) { + int t = Util.getTypeIndex(type); + if (t < 0 || t > TYPE_Object_index) { + throw new IllegalArgumentException("Cannot store local of type " + type); + } + if (index < 16) { + return preallocated[t * 16 + index]; + } else { + return new StoreInstruction((short) (OP_istore + t), index); + } + } + + /** + * @return the index of the local variable stored + */ + public int getVarIndex() { + return index; + } + + public String getType() { + if (opcode < OP_istore_0) { + return indexedTypes[opcode - OP_istore]; + } else { + return indexedTypes[(opcode - OP_istore_0) / 4]; + } + } + + public boolean equals(Object o) { + if (o instanceof StoreInstruction) { + StoreInstruction i = (StoreInstruction) o; + return i.index == index && i.opcode == opcode; + } else { + return false; + } + } + + public int hashCode() { + return opcode + index * 148091891; + } + + public int getPoppedCount() { + return 1; + } + + public String toString() { + return "LocalStore(" + getType() + "," + index + ")"; + } + + public void visit(Visitor v) { + v.visitLocalStore(this); + } + /* (non-Javadoc) + * @see com.ibm.domo.cfg.IInstruction#isPEI() + */ + public boolean isPEI() { + return false; + } +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/SwapInstruction.java b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/SwapInstruction.java new file mode 100644 index 000000000..a1f897abd --- /dev/null +++ b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/SwapInstruction.java @@ -0,0 +1,56 @@ +/******************************************************************************* + * 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.shrikeBT; + +/** + * This instruction represents the swap instruction, which swaps the two values + * on top of the working stack. + */ +public final class SwapInstruction extends Instruction { + protected SwapInstruction() { + } + + private final static SwapInstruction preallocated = new SwapInstruction(); + + public static SwapInstruction make() { + return preallocated; + } + + public boolean equals(Object o) { + if (o instanceof SwapInstruction) { + return true; + } else { + return false; + } + } + + public int hashCode() { + return 84323111; + } + + public int getPoppedCount() { + return 2; + } + + public String toString() { + return "Swap()"; + } + + public void visit(Visitor v) { + v.visitSwap(this); + } + /* (non-Javadoc) + * @see com.ibm.domo.cfg.IInstruction#isPEI() + */ + public boolean isPEI() { + return false; + } +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/SwitchInstruction.java b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/SwitchInstruction.java new file mode 100644 index 000000000..69bed9e08 --- /dev/null +++ b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/SwitchInstruction.java @@ -0,0 +1,136 @@ +/******************************************************************************* + * 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.shrikeBT; + +import java.util.Arrays; + +/** + * This instruction represents all forms of switch instructions. + */ +public final class SwitchInstruction extends Instruction { + private int[] casesAndLabels; + private int defaultLabel; + + protected SwitchInstruction(short opcode, int[] casesAndLabels, int defaultLabel) { + this.casesAndLabels = casesAndLabels; + this.defaultLabel = defaultLabel; + this.opcode = opcode; + } + + /** + * @return the label which is branched to if none of the cases match + */ + public int getDefaultLabel() { + return defaultLabel; + } + + /** + * @return an array of flattened (case, label) pairs, sorted in increasing + * order by case + */ + public int[] getCasesAndLabels() { + return casesAndLabels; + } + + /** + * Make a switch instruction. + * + * @param casesAndLabels + * an array of flattened (case, label) pairs, sorted in increasing + * order by case + * @param defaultLabel + * the default label to branch to if no cases match + */ + public static SwitchInstruction make(int[] casesAndLabels, int defaultLabel) { + short opcode = OP_tableswitch; + + for (int i = 2; i < casesAndLabels.length; i += 2) { + int curCase = casesAndLabels[i]; + int lastCase = casesAndLabels[i - 2]; + if (curCase <= lastCase) { + throw new IllegalArgumentException("Cases and labels array must be sorted by case"); + } + if (curCase != lastCase + 1) { + opcode = OP_lookupswitch; + } + } + + if (casesAndLabels.length == 0) { + opcode = OP_lookupswitch; + } + + return new SwitchInstruction(opcode, casesAndLabels, defaultLabel); + } + + public boolean isFallThrough() { + return false; + } + + public int[] getBranchTargets() { + int[] r = new int[casesAndLabels.length / 2 + 1]; + r[0] = defaultLabel; + for (int i = 1; i < r.length; i++) { + r[i] = casesAndLabels[(i - 1) * 2 + 1]; + } + return r; + } + + public Instruction redirectTargets(int[] targetMap) { + int[] cs = new int[casesAndLabels.length]; + for (int i = 0; i < cs.length; i += 2) { + cs[i] = casesAndLabels[i]; + cs[i + 1] = targetMap[casesAndLabels[i + 1]]; + } + return make(cs, targetMap[defaultLabel]); + } + + public boolean equals(Object o) { + if (o instanceof SwitchInstruction) { + SwitchInstruction i = (SwitchInstruction) o; + return i.defaultLabel == defaultLabel && Arrays.equals(i.casesAndLabels, casesAndLabels); + } else { + return false; + } + } + + public int hashCode() { + int h = defaultLabel * 1348091 + 111311; + for (int i = 0; i < casesAndLabels.length; i++) { + h += (i * 9301 + 38101) * casesAndLabels[i]; + } + return h; + } + + public int getPoppedCount() { + return 1; + } + + public String toString() { + StringBuffer b = new StringBuffer("Switch("); + b.append(defaultLabel); + for (int i = 0; i < casesAndLabels.length; i++) { + b.append(','); + b.append(casesAndLabels[i]); + } + b.append(")"); + return b.toString(); + } + + public void visit(Visitor v) { + v.visitSwitch(this); + } + /* (non-Javadoc) + * @see com.ibm.domo.cfg.IInstruction#isPEI() + */ + public boolean isPEI() { + return false; + } +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/ThrowInstruction.java b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/ThrowInstruction.java new file mode 100644 index 000000000..65cc30f86 --- /dev/null +++ b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/ThrowInstruction.java @@ -0,0 +1,56 @@ +/******************************************************************************* + * 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.shrikeBT; + +/** + * This class represents the athrow instruction. + */ +public final class ThrowInstruction extends Instruction { + private static final ThrowInstruction preallocated = new ThrowInstruction(); + + protected ThrowInstruction() { + this.opcode = OP_athrow; + } + + public static ThrowInstruction make() { + return preallocated; + } + + public boolean equals(Object o) { + return o instanceof ThrowInstruction; + } + + public boolean isFallThrough() { + return false; + } + + public int hashCode() { + return 99651; + } + + public int getPoppedCount() { + return 1; + } + + public void visit(Visitor v) { + v.visitThrow(this); + } + + public String toString() { + return "Throw()"; + } + /* (non-Javadoc) + * @see com.ibm.domo.cfg.IInstruction#isPEI() + */ + public boolean isPEI() { + return true; + } +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/UnaryOpInstruction.java b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/UnaryOpInstruction.java new file mode 100644 index 000000000..d6a6334e2 --- /dev/null +++ b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/UnaryOpInstruction.java @@ -0,0 +1,97 @@ +/******************************************************************************* + * 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.shrikeBT; + +/** + * This class represents unary operators where the result is the same type as + * the operand. + */ +public final class UnaryOpInstruction extends Instruction { + public interface IOperator {} + + public static enum Operator implements IOperator { + NEG; + + @Override + public String toString() { + return super.toString().toLowerCase(); + } + } + + protected UnaryOpInstruction(short opcode) { + this.opcode = opcode; + } + + private final static UnaryOpInstruction[] preallocated = preallocate(); + + private static UnaryOpInstruction[] preallocate() { + UnaryOpInstruction[] r = new UnaryOpInstruction[OP_dneg - OP_ineg + 1]; + for (int i = 0; i < r.length; i++) { + r[i] = new UnaryOpInstruction((short) (OP_ineg + i)); + } + return r; + } + + public static UnaryOpInstruction make(String type, Operator operator) { + int t = Util.getTypeIndex(type); + if (t < 0 || t > TYPE_double_index) { + throw new IllegalArgumentException("Type " + type + " cannot have a unary operator applied"); + } + return preallocated[t]; + } + + public boolean equals(Object o) { + if (o instanceof UnaryOpInstruction) { + UnaryOpInstruction i = (UnaryOpInstruction) o; + return i.opcode == opcode; + } else { + return false; + } + } + + public Operator getOperator() { + return Operator.NEG; + } + + public int hashCode() { + return opcode; + } + + public int getPoppedCount() { + return 1; + } + + public String getPushedType(String[] types) { + return getType(); + } + + public byte getPushedWordSize() { + return Util.getWordSize(getType()); + } + + public String getType() { + return indexedTypes[opcode - OP_ineg]; + } + + public void visit(Visitor v) { + v.visitUnaryOp(this); + } + + public String toString() { + return "UnaryOp(" + getType() + "," + getOperator() + ")"; + } + /* (non-Javadoc) + * @see com.ibm.domo.cfg.IInstruction#isPEI() + */ + public boolean isPEI() { + return false; + } +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/Util.java b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/Util.java new file mode 100644 index 000000000..61da87a71 --- /dev/null +++ b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/Util.java @@ -0,0 +1,540 @@ +/******************************************************************************* + * 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.shrikeBT; + +import java.io.IOException; +import java.io.InputStream; +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.util.Arrays; +import java.util.HashMap; + +import com.ibm.wala.shrikeBT.IInvokeInstruction.Dispatch; + +/** + * This class contains miscellaneous useful functions. + * + * In the documentation below, we refer to a 'Java class name'. These are + * formatted according to the rules for Class.forName() and Class.getName(). A + * Java class name must use '$' to separate inner class names from their + * containing class. There is no way to for Shrike to disambiguate 'A.B' + * otherwise. + */ +public final class Util { + private Util() { + // prevent instantiation + } + + /** + * @return the JVM "stack word size" for the given JVM type + */ + public static byte getWordSize(String s) { + return getWordSize(s, 0); + } + + /** + * @return the JVM "stack word size" for the given JVM type, looking at index + * 'index' + */ + public static byte getWordSize(String s, int index) { + switch (s.charAt(index)) { + case 'V': + return 0; + case 'J': + case 'D': + return 2; + default: + return 1; + } + } + + /** + * Computes the character length of the internal JVM type given by + * s.substring(i). + */ + public static int getTypeLength(String s, int i) { + switch (s.charAt(i)) { + case 'L': + return s.indexOf(';', i) - i + 1; + case '[': + return getTypeLength(s, i + 1) + 1; + default: + return 1; + } + } + + /** + * Compute the total number of JVM "stack words" occupied by the method + * parameters for method signature "type". Any "this" parameter is not + * included. + */ + public static int getParamsWordSize(String type) { + int index = 1; + int count = 0; + + if (type.indexOf(')', 1) < 0) { + throw new IllegalArgumentException("Invalid method descriptor (missing ')'): " + type); + } + while (type.charAt(index) != ')') { + count += getWordSize(type, index); + index += getTypeLength(type, index); + } + return count; + } + + /** + * Convert a fully-qualified Java class name ('.' separated) into an internal + * JVM type name ('/' separated, starting with 'L' and ending with ';'). + */ + public static String makeType(String c) { + if (c.startsWith("[")) { + return c.replace('.', '/'); + } else if (!c.endsWith(";")) { + return "L" + c.replace('.', '/') + ";"; + } else { + return c; + } + } + + /** + * Convert a fully-qualified Java type name (either primitive or class name, + * '.' separated) into an internal JVM type name (one letter for primitive and + * '/' separated, starting with 'L' and ending with ';' for class name). + */ + public static String makeTypeAll(String c) { + String alias = typeAliases.get(c); + if (alias != null) { + return alias; + } else { + return makeType(c); + } + } + + /** + * Convert a JVM type name back into a Java class name. + */ + public static String makeClass(String t) { + if (t.startsWith("[")) { + return t; + } else if (!t.startsWith("L")) { + throw new IllegalArgumentException(t + " is not a valid class type"); + } else { + return t.substring(1, t.length() - 1).replace('/', '.'); + } + } + + /** + * Convert a JVM type name (either for a primitive or a class name) into a + * Java type name. + */ + public static String makeClassAll(String t) { + String alias = classAliases.get(t); + if (alias != null) { + return alias; + } else { + return makeClass(t); + } + } + + private static HashMap classAliases; + private static HashMap typeAliases; + + private static void addAlias(String c, String t) { + typeAliases.put(c, t); + classAliases.put(t, c); + } + static { + typeAliases = new HashMap(); + classAliases = new HashMap(); + addAlias("void", "V"); + addAlias("int", "I"); + addAlias("long", "J"); + addAlias("float", "F"); + addAlias("double", "D"); + addAlias("byte", "B"); + addAlias("char", "C"); + addAlias("short", "S"); + addAlias("boolean", "Z"); + } + + /** + * Compute the JVM type name for an actual Java class. Names such as "int", + * "void", etc are also converted to their JVM type names. + */ + public static String makeType(Class c) { + String name = c.getName(); + String alias = typeAliases.get(name); + if (alias != null) { + return alias; + } else { + return makeType(name); + } + } + + /** + * Compute the number of parameters given by method signature "type". Any + * "this" parameter is not included. + */ + public static int getParamsCount(String type) { + int index = 1; + int count = 0; + + while (type.charAt(index) != ')') { + count++; + index += getTypeLength(type, index); + } + return count; + } + + /** + * Extract the types of the parameters given by method signature "type". + * + * @param thisClassType + * null if the method is static, otherwise the type of "this" + * @return an array of the parameter types in order, including "this" as the + * first parameter if thisClassType was non-null + */ + public static String[] getParamsTypes(String thisClassType, String type) { + int count = thisClassType != null ? 1 : 0; + String[] r = new String[getParamsCount(type) + count]; + int index = 1; + + if (thisClassType != null) { + r[0] = thisClassType; + } + + while (type.charAt(index) != ')') { + int len = getTypeLength(type, index); + + r[count] = type.substring(index, index + len); + count++; + index += len; + } + return r; + } + + /** + * Compute the types of the local variables on entry to a method. Similar to + * "getParamsTypes" except null array entries are inserted to account for + * unused local variables because of 2-word parameter values. + */ + public static String[] getParamsTypesInLocals(String thisClassType, String type) { + int count = thisClassType != null ? 1 : 0; + String[] r = new String[getParamsWordSize(type) + count]; + int index = 1; + + if (thisClassType != null) { + r[0] = thisClassType; + } + + while (type.charAt(index) != ')') { + int len = getTypeLength(type, index); + String t = getStackType(type.substring(index, index + len)); + + r[count] = t; + count += getWordSize(t); + index += len; + } + return r; + } + + /** + * Compute the promoted type that the JVM uses to manipulate values of type + * "t" on its working stack. + */ + public static String getStackType(String t) { + switch (t.charAt(0)) { + case 'Z': + case 'C': + case 'B': + case 'S': + return "I"; + default: + return t; + } + } + + /** + * Compute the type "array of t". + */ + public static String makeArray(String t) { + return ("[" + t).intern(); + } + + /** + * @return true iff t is an array type + */ + public static boolean isArrayType(String t) { + if (t == null) { + return false; + } else { + switch (t.charAt(0)) { + case '[': + return true; + default: + return false; + } + } + } + + /** + * @return true iff t is a primitive type + */ + public static boolean isPrimitiveType(String t) { + if (t == null) { + return false; + } else { + switch (t.charAt(0)) { + case 'L': + case '[': + return false; + default: + return true; + } + } + } + + /** + * Get the return type from a method signature. + */ + public static String getReturnType(String s) { + return s.substring(s.lastIndexOf(')') + 1); + } + + /** + * General "print an error" routine. + */ + public static void error(String s) { + System.err.println(s); + (new Error("Stack Trace")).printStackTrace(); + } + + /** + * Given a Java Method, compute the VM-style type signature. + */ + public static String computeSignature(Class[] params, Class result) { + StringBuffer buf = new StringBuffer(); + buf.append("("); + for (int i = 0; i < params.length; i++) { + buf.append(makeType(params[i])); + } + buf.append(")"); + buf.append(makeType(result)); + return buf.toString(); + } + + /** + * Make an Instruction which loads the value of a field, given its name and + * Java Class. The field type is obtained using reflection. + */ + public static GetInstruction makeGet(Class c, String name) { + try { + Field f = c.getField(name); + return GetInstruction.make(makeType(f.getType()), makeType(c), name, (f.getModifiers() & Constants.ACC_STATIC) != 0); + } catch (SecurityException e) { + throw new IllegalArgumentException(e.getMessage()); + } catch (NoSuchFieldException e) { + throw new IllegalArgumentException(e.getMessage()); + } + } + + /** + * Make an Instruction which stores the value of a field, given its name and + * Java Class. The field type is obtained using reflection. + */ + public static PutInstruction makePut(Class c, String name) { + try { + Field f = c.getField(name); + return PutInstruction.make(makeType(f.getType()), makeType(c), name, (f.getModifiers() & Constants.ACC_STATIC) != 0); + } catch (SecurityException e) { + throw new IllegalArgumentException(e.getMessage()); + } catch (NoSuchFieldException e) { + throw new IllegalArgumentException(e.getMessage()); + } + } + + private static String makeName(String name, Class[] paramTypes) { + if (paramTypes == null) { + return name; + } else { + StringBuffer buf = new StringBuffer(name); + buf.append("("); + for (int i = 0; i < paramTypes.length; i++) { + if (i > 0) { + buf.append(","); + } + buf.append(paramTypes[i].getName()); + } + buf.append(")"); + return buf.toString(); + } + } + + public static Method findMethod(Class c, String name) { + return findMethod(c, name, null); + } + + public static Method findMethod(Class c, String name, Class[] paramTypes) { + Method[] methods = c.getMethods(); + Method result = null; + for (int i = 0; i < methods.length; i++) { + Method m = methods[i]; + if (m.getName().equals(name) && (paramTypes == null || Arrays.equals(m.getParameterTypes(), paramTypes))) { + if (result != null) { + throw new IllegalArgumentException("Method " + makeName(name, paramTypes) + " is ambiguous in class " + c); + } + result = m; + } + } + return result; + } + + /** + * Make an Instruction which calls a method, given its name, Java Class, and a + * list of parameter classes to use for overload resolution. Method + * information is obtained using reflection. + */ + public static InvokeInstruction makeInvoke(Class c, String name, Class[] paramTypes) { + InvokeInstruction result = null; + + if (name.equals("")) { + Constructor[] cs = c.getConstructors(); + for (int i = 0; i < cs.length; i++) { + Constructor con = cs[i]; + if (paramTypes == null || Arrays.equals(con.getParameterTypes(), paramTypes)) { + if (result != null) { + throw new IllegalArgumentException("Constructor " + makeName(name, paramTypes) + " is ambiguous in class " + c); + } + result = InvokeInstruction.make(computeSignature(con.getParameterTypes(), Void.TYPE), makeType(c), name, Dispatch.SPECIAL); + } + } + } else { + Method m = findMethod(c, name, paramTypes); + if (m != null) { + Dispatch opcode = Dispatch.VIRTUAL; + if ((m.getModifiers() & Constants.ACC_STATIC) != 0) { + opcode = Dispatch.STATIC; + } else if (m.getDeclaringClass().isInterface()) { + opcode = Dispatch.INTERFACE; + } + result = InvokeInstruction.make(computeSignature(m.getParameterTypes(), m.getReturnType()), makeType(c), name, opcode); + } + } + + if (result == null) { + throw new IllegalArgumentException("Method " + makeName(name, paramTypes) + " is not present in class " + c); + } else { + return result; + } + } + + /** + * Make an Instruction which calls a method, given its name and Java Class. + * Method information is obtained using reflection. If there is more than one + * method with the given name, an error will be thrown. + */ + public static InvokeInstruction makeInvoke(Class c, String name) { + return makeInvoke(c, name, null); + } + + /** + * Compute the type index constant (Constants.TYPE_...) from the JVM type. + * Returns -1 if the type is not one of the predefined constants. + */ + static int getTypeIndex(String t) { + if (t == null) { + return -1; + } else { + int len = t.length(); + if (len < 1) { + return -1; + } else { + char ch = t.charAt(0); + if (ch < typeIndices.length) { + int r = typeIndices[ch]; + if (r != 4) { + if (len > 1) { + return -1; + } else { + return r; + } + } else { + return r; + } + } else { + return -1; + } + } + } + } + + private static final byte[] typeIndices = makeTypeIndices(); + + private static byte[] makeTypeIndices() { + byte[] r = new byte[128]; + for (int i = 0; i < r.length; i++) { + r[i] = -1; + } + r['I'] = 0; + r['J'] = 1; + r['F'] = 2; + r['D'] = 3; + r['L'] = 4; + r['['] = 4; + r['B'] = 5; + r['C'] = 6; + r['S'] = 7; + r['Z'] = 8; + + return r; + } + + public static void readFully(InputStream s, byte[] bytes) throws IOException { + int offset = 0; + while (offset < bytes.length) { + int r = s.read(bytes, offset, bytes.length - offset); + if (r < 0) { + throw new IOException("Class truncated"); + } + offset += r; + } + } + + public static byte[] readFully(InputStream s) throws IOException { + byte[] bytes = new byte[s.available()]; + readFully(s, bytes); + int b = s.read(); + if (b < 0) { + return bytes; + } else { + byte[] big = new byte[bytes.length * 2 + 1]; + System.arraycopy(bytes, 0, big, 0, bytes.length); + big[bytes.length] = (byte) b; + int offset = bytes.length + 1; + do { + if (big.length == offset) { + // grow array by factor of 2 + bytes = new byte[offset * 2]; + System.arraycopy(big, 0, bytes, 0, offset); + big = bytes; + } + int r = s.read(big, offset, big.length - offset); + if (r < 0) { + bytes = new byte[offset]; + System.arraycopy(big, 0, bytes, 0, offset); + return bytes; + } + offset += r; + } while (true); + } + } +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/analysis/Analyzer.java b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/analysis/Analyzer.java new file mode 100644 index 000000000..12ecf3283 --- /dev/null +++ b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/analysis/Analyzer.java @@ -0,0 +1,662 @@ +/******************************************************************************* + * 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.shrikeBT.analysis; + +import java.io.IOException; +import java.io.Writer; +import java.util.ArrayList; +import java.util.BitSet; +import java.util.List; + +import com.ibm.wala.shrikeBT.DupInstruction; +import com.ibm.wala.shrikeBT.ExceptionHandler; +import com.ibm.wala.shrikeBT.Instruction; +import com.ibm.wala.shrikeBT.LoadInstruction; +import com.ibm.wala.shrikeBT.MethodData; +import com.ibm.wala.shrikeBT.StoreInstruction; +import com.ibm.wala.shrikeBT.SwapInstruction; +import com.ibm.wala.shrikeBT.Util; + +/** + * @author roca + */ +public class Analyzer { + // inputs + protected boolean isStatic; + protected String classType; + protected String signature; + protected Instruction[] instructions; + protected ExceptionHandler[][] handlers; + protected ClassHierarchyProvider hierarchy; + + // working + protected int maxStack; + protected int maxLocals; + protected String[][] stacks; + protected String[][] locals; + protected int[] stackSizes; + protected BitSet basicBlockStarts; + protected int[][] backEdges; + + protected final static String[] noStrings = new String[0]; + protected final static int[] noEdges = new int[0]; + + public Analyzer(boolean isStatic, String classType, String signature, Instruction[] instructions, ExceptionHandler[][] handlers) { + this.classType = classType; + this.isStatic = isStatic; + this.signature = signature; + this.instructions = instructions; + this.handlers = handlers; + } + + /** + * Use class hierarchy information in 'h'. If this method is not called or h + * provides only partial hierarchy information, the verifier behaves + * optimistically. + */ + final public void setClassHierarchy(ClassHierarchyProvider h) { + this.hierarchy = h; + } + + private void addBackEdge(int from, int to) { + int[] oldEdges = backEdges[from]; + if (oldEdges == null) { + backEdges[from] = new int[] { to }; + } else if (oldEdges[oldEdges.length - 1] < 0) { + int left = 1; + int right = oldEdges.length - 1; + while (true) { + if (right - left < 2) { + if (oldEdges[left] < 0) { + break; + } else { + if (oldEdges[right] >= 0) + throw new Error("Failed binary search"); + left = right; + break; + } + } else { + int mid = (left + right) / 2; + if (oldEdges[mid] < 0) { + right = mid; + } else { + left = mid + 1; + } + } + } + oldEdges[left] = to; + } else { + int[] newEdges = new int[oldEdges.length * 2]; + System.arraycopy(oldEdges, 0, newEdges, 0, oldEdges.length); + newEdges[oldEdges.length] = to; + for (int i = oldEdges.length + 1; i < newEdges.length; i++) { + newEdges[i] = -1; + } + backEdges[from] = newEdges; + } + } + + final public int[][] getBackEdges() { + if (backEdges != null) { + return backEdges; + } + + backEdges = new int[instructions.length][]; + + for (int i = 0; i < instructions.length; i++) { + Instruction instr = instructions[i]; + int[] targets = instr.getBranchTargets(); + for (int j = 0; j < targets.length; j++) { + addBackEdge(targets[j], i); + } + ExceptionHandler[] hs = handlers[i]; + for (int j = 0; j < hs.length; j++) { + addBackEdge(hs[j].getHandler(), i); + } + } + + for (int i = 0; i < backEdges.length; i++) { + int[] back = backEdges[i]; + if (back == null) { + backEdges[i] = noEdges; + } else if (back[back.length - 1] < 0) { + int j = back.length; + while (back[j - 1] < 0) { + j--; + } + int[] newBack = new int[j]; + System.arraycopy(back, 0, newBack, 0, newBack.length); + backEdges[i] = newBack; + } + } + + return backEdges; + } + + final public boolean isSubtypeOf(String t1, String t2) { + return ClassHierarchy.isSubtypeOf(hierarchy, t1, t2) != ClassHierarchy.NO; + } + + final public String findCommonSupertype(String t1, String t2) { + return ClassHierarchy.findCommonSupertype(hierarchy, t1, t2); + } + + final public BitSet getBasicBlockStarts() { + if (basicBlockStarts != null) { + return basicBlockStarts; + } + + BitSet r = new BitSet(instructions.length); + + r.set(0); + for (int i = 0; i < instructions.length; i++) { + int[] targets = instructions[i].getBranchTargets(); + + for (int j = 0; j < targets.length; j++) { + r.set(targets[j]); + } + } + for (int i = 0; i < handlers.length; i++) { + ExceptionHandler[] hs = handlers[i]; + if (hs != null) { + for (int j = 0; j < hs.length; j++) { + r.set(hs[j].getHandler()); + } + } + } + + basicBlockStarts = r; + return r; + } + + final public Instruction[] getInstructions() { + return instructions; + } + + private void getReachableRecursive(int from, BitSet reachable, boolean followHandlers, BitSet mask) { + while (true) { + // stop if we've already visited this instruction or if we've gone outside + // the mask + if (reachable.get(from) || (mask != null && !mask.get(from))) { + return; + } + + reachable.set(from); + + Instruction instr = instructions[from]; + int[] targets = instr.getBranchTargets(); + for (int i = 0; i < targets.length; i++) { + getReachableRecursive(targets[i], reachable, followHandlers, mask); + } + + if (followHandlers) { + ExceptionHandler[] hs = handlers[from]; + for (int i = 0; i < hs.length; i++) { + getReachableRecursive(hs[i].getHandler(), reachable, followHandlers, mask); + } + } + + if (instr.isFallThrough()) { + ++from; + continue; + } + + break; + } + } + + final public BitSet getReachableFrom(int from) { + return getReachableFrom(from, true, null); + } + + final public void getReachableFromUpdate(int from, BitSet reachable, boolean followHandlers, BitSet mask) { + reachable.clear(); + getReachableRecursive(from, reachable, followHandlers, mask); + } + + final public BitSet getReachableFrom(int from, boolean followHandlers, BitSet mask) { + BitSet reachable = new BitSet(); + getReachableRecursive(from, reachable, followHandlers, mask); + return reachable; + } + + private void getReachingRecursive(int to, BitSet reaching, BitSet mask) { + while (true) { + // stop if we've already visited this instruction or if we've gone outside + // the mask + if (reaching.get(to) || (mask != null && !mask.get(to))) { + return; + } + + reaching.set(to); + + int[] targets = backEdges[to]; + for (int i = 0; i < targets.length; i++) { + getReachingRecursive(targets[i], reaching, mask); + } + + if (to > 0 && instructions[to - 1].isFallThrough()) { + --to; + continue; + } + + break; + } + } + + private void getReachingBase(int to, BitSet reaching, BitSet mask) { + int[] targets = backEdges[to]; + for (int i = 0; i < targets.length; i++) { + getReachingRecursive(targets[i], reaching, mask); + } + + if (to > 0 && instructions[to - 1].isFallThrough()) { + getReachingRecursive(to - 1, reaching, mask); + } + } + + final public void getReachingToUpdate(int to, BitSet reaching, BitSet mask) { + getBackEdges(); + reaching.clear(); + getReachingBase(to, reaching, mask); + } + + final public BitSet getReachingTo(int to, BitSet mask) { + getBackEdges(); + BitSet reaching = new BitSet(); + getReachingBase(to, reaching, mask); + return reaching; + } + + final public BitSet getReachingTo(int to) { + return getReachingTo(to, null); + } + + private void computeStackSizesAt(int[] stackSizes, int i, int size) throws FailureException { + while (true) { + if (stackSizes[i] >= 0) { + if (size != stackSizes[i]) { + throw new FailureException(i, "Stack size mismatch", null); + } + return; + } + stackSizes[i] = size; + + Instruction instr = instructions[i]; + if (instr instanceof DupInstruction) { + size += ((DupInstruction) instr).getSize(); + } else if (instr instanceof SwapInstruction) { + } else { + size -= instr.getPoppedCount(); + if (instr.getPushedWordSize() > 0) { + size++; + } + } + + int[] targets = instr.getBranchTargets(); + for (int j = 0; j < targets.length; j++) { + computeStackSizesAt(stackSizes, targets[j], size); + } + ExceptionHandler[] hs = handlers[i]; + for (int j = 0; j < hs.length; j++) { + computeStackSizesAt(stackSizes, hs[j].getHandler(), 1); + } + + if (!instr.isFallThrough()) { + return; + } + i++; + } + } + + /** + * This exception is thrown by verify() when it fails. + */ + public static final class FailureException extends Exception { + + private static final long serialVersionUID = -7663520961403117526L; + private int offset; + private String reason; + private List path; + + FailureException(int offset, String reason, List path) { + super(reason + " at offset " + offset); + this.offset = offset; + this.reason = reason; + this.path = path; + } + + /** + * @return the index of the Instruction which failed to verify + */ + public int getOffset() { + return offset; + } + + /** + * @return a description of the reason why verification failed + */ + public String getReason() { + return reason; + } + + /** + * @return a list of PathElements describing how the type that caused the + * error was propagated from its origin to the point of the error + */ + public List getPath() { + return path; + } + + void setPath(List path) { + this.path = path; + } + + /** + * Print the path to the given stream, if there is one. + */ + public void printPath(Writer w) throws IOException { + if (path != null) { + for (int i = 0; i < path.size(); i++) { + PathElement elem = path.get(i); + String[] stack = elem.stack; + String[] locals = elem.locals; + w.write("Offset " + elem.index + ": ["); + for (int j = 0; j < stack.length; j++) { + if (j > 0) { + w.write(","); + } + w.write(stack[j]); + } + w.write("], ["); + for (int j = 0; j < locals.length; j++) { + if (j > 0) { + w.write(","); + } + w.write(locals[j] == null ? "?" : locals[j]); + } + w.write("]\n"); + } + } + } + } + + public static final class PathElement { + int index; + String[] stack; + String[] locals; + + PathElement(int index, String[] stack, String[] locals) { + this.stack = (String[]) stack.clone(); + this.locals = (String[]) locals.clone(); + this.index = index; + } + + /** + * @return the bytecode offset of the instruction causing a value transfer. + */ + public int getIndex() { + return index; + } + + /** + * @return the types of the local variabls at the instruction. + */ + public String[] getLocals() { + return locals; + } + + /** + * @return the types of the working stack at the instruction. + */ + public String[] getStack() { + return stack; + } + } + + private String[] cutArray(String[] a, int len) { + if (len == 0) { + return noStrings; + } else { + String[] r = new String[len]; + System.arraycopy(a, 0, r, 0, len); + return r; + } + } + + private boolean mergeTypes(int i, String[] curStack, int curStackSize, String[] curLocals, int curLocalsSize, List path) + throws FailureException { + boolean changed = false; + + if (stacks[i] == null) { + stacks[i] = cutArray(curStack, curStackSize); + changed = true; + } else { + String[] st = stacks[i]; + if (st.length != curStackSize) { + throw new FailureException(i, "Stack size mismatch: " + st.length + ", " + curStackSize, path); + } + for (int j = 0; j < curStackSize; j++) { + String t = findCommonSupertype(st[j], curStack[j]); + if (t != st[j]) { + if (t == null) { + throw new FailureException(i, "Stack type mismatch at " + j + " (" + st[j] + " vs " + curStack[j] + ")", path); + } + st[j] = t; + changed = true; + } + } + } + + if (locals[i] == null) { + locals[i] = cutArray(curLocals, curLocalsSize); + changed = true; + } else { + String[] ls = locals[i]; + for (int j = 0; j < ls.length; j++) { + String t = findCommonSupertype(ls[j], curLocals[j]); + if (t != ls[j]) { + ls[j] = t; + changed = true; + } + } + } + + return changed; + } + + /** + * A PathElement describes a point where a value is moved from one location to + * another. + */ + private void computeTypes(int i, TypeVisitor visitor, BitSet makeTypesAt, List path) throws FailureException { + final String[] curStack = new String[maxStack]; + final String[] curLocals = new String[maxLocals]; + + while (true) { + if (path != null) { + path.add(new PathElement(i, stacks[i], locals[i])); + } + + int curStackSize = stacks[i].length; + System.arraycopy(stacks[i], 0, curStack, 0, curStackSize); + + final int[] curLocalsSize = { locals[i].length }; + System.arraycopy(locals[i], 0, curLocals, 0, curLocalsSize[0]); + + Instruction.Visitor localsUpdate = new Instruction.Visitor() { + public void visitLocalLoad(LoadInstruction instruction) { + String t = curLocals[instruction.getVarIndex()]; + curStack[0] = t; + } + + public void visitLocalStore(StoreInstruction instruction) { + int index = instruction.getVarIndex(); + curLocals[index] = curStack[0]; + if (index >= curLocalsSize[0]) { + curLocalsSize[0] = index + 1; + } + } + }; + + boolean restart = false; + while (true) { + Instruction instr = instructions[i]; + int popped = instr.getPoppedCount(); + + if (curStackSize < popped) { + throw new FailureException(i, "Stack underflow", path); + } + + if (visitor != null) { + visitor.setState(i, path, curStack, curLocals); + instr.visit(visitor); + if (!visitor.shouldContinue()) { + return; + } + } + + if (instr instanceof DupInstruction) { + DupInstruction d = (DupInstruction) instr; + int size = d.getSize(); + + System.arraycopy(curStack, popped, curStack, popped + size, curStackSize - popped); + System.arraycopy(curStack, 0, curStack, popped, size); + curStackSize += size; + } else if (instr instanceof SwapInstruction) { + String s = curStack[0]; + curStack[0] = curStack[1]; + curStack[1] = s; + } else { + String pushed = instr.getPushedType(curStack); + if (pushed != null) { + System.arraycopy(curStack, popped, curStack, 1, curStackSize - popped); + curStack[0] = Util.getStackType(pushed); + instr.visit(localsUpdate); // visit localLoad after pushing + curStackSize -= popped - 1; + } else { + instr.visit(localsUpdate); // visit localStore before popping + System.arraycopy(curStack, popped, curStack, 0, curStackSize - popped); + curStackSize -= popped; + } + } + + int[] targets = instr.getBranchTargets(); + for (int j = 0; j < targets.length; j++) { + if (mergeTypes(targets[j], curStack, curStackSize, curLocals, curLocalsSize[0], path)) { + computeTypes(targets[j], visitor, makeTypesAt, path); + } + } + + if (!instr.isFallThrough()) { + break; + } else { + i++; + if (makeTypesAt.get(i)) { + if (mergeTypes(i, curStack, curStackSize, curLocals, curLocalsSize[0], path)) { + restart = true; + break; + } + if (path != null) { + path.remove(path.size() - 1); + } + return; + } + } + } + if (!restart) { + break; + } + } + if (path != null) { + path.remove(path.size() - 1); + } + } + + public int[] getStackSizes() throws FailureException { + if (stackSizes != null) { + return stackSizes; + } + + stackSizes = new int[instructions.length]; + + for (int i = 0; i < stackSizes.length; i++) { + stackSizes[i] = -1; + } + computeStackSizesAt(stackSizes, 0, 0); + + return stackSizes; + } + + private void computeMaxLocals() { + maxLocals = locals[0].length; + for (int i = 0; i < instructions.length; i++) { + Instruction instr = instructions[i]; + if (instr instanceof LoadInstruction) { + maxLocals = Math.max(maxLocals, ((LoadInstruction) instr).getVarIndex() + 1); + } else if (instr instanceof StoreInstruction) { + maxLocals = Math.max(maxLocals, ((StoreInstruction) instr).getVarIndex() + 1); + } + } + } + + final protected void initTypeInfo() throws FailureException { + stacks = new String[instructions.length][]; + locals = new String[instructions.length][]; + + stacks[0] = noStrings; + locals[0] = Util.getParamsTypesInLocals(isStatic ? null : classType, signature); + int[] stackSizes = getStackSizes(); + maxStack = 0; + for (int i = 0; i < stackSizes.length; i++) { + maxStack = Math.max(maxStack, stackSizes[i]); + } + computeMaxLocals(); + } + + /** + * Verify the method and compute types at every program point. + * + * @throws FailureException + * the method contains invalid bytecode + */ + final public void computeTypes(TypeVisitor v, BitSet makeTypesAt, boolean wantPath) throws FailureException { + initTypeInfo(); + computeTypes(0, v, makeTypesAt, wantPath ? new ArrayList() : null); + } + + public abstract class TypeVisitor extends Instruction.Visitor { + public abstract void setState(int index, List path, String[] curStack, String[] curLocals); + + public abstract boolean shouldContinue(); + } + + /** + * @return an array indexed by instruction index; each entry is an array of + * Strings giving the types of the locals at that instruction. + */ + final public String[][] getLocalTypes() { + return locals; + } + + /** + * @return an array indexed by instruction index; each entry is an array of + * Strings giving the types of the stack elements at that instruction. + * The top of the stack is the last element of the array. + */ + final public String[][] getStackTypes() { + return stacks; + } + + public Analyzer(MethodData info) { + this(info.getIsStatic(), info.getClassType(), info.getSignature(), info.getInstructions(), info.getHandlers()); + } +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/analysis/ClassHierarchy.java b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/analysis/ClassHierarchy.java new file mode 100644 index 000000000..75b0cdafe --- /dev/null +++ b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/analysis/ClassHierarchy.java @@ -0,0 +1,414 @@ +/******************************************************************************* + * 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.shrikeBT.analysis; + +import java.util.HashSet; +import java.util.Iterator; + +import com.ibm.wala.shrikeBT.Constants; + +/** + * This class takes the raw information from a ClassHierarchyProvider and + * computes type operations (subtype check, type union). All operations are + * static. + * + * Because ClassHierarchyProvider sometimes only provides partial information, + * these routines sometimes answer "don't know". + */ +public final class ClassHierarchy { + private ClassHierarchy() { + } + + /** + * Equals Constants.NO + */ + public static final int NO = Constants.NO; + /** + * Equals Constants.YES + */ + public static final int YES = Constants.YES; + /** + * Equals Constants.MAYBE + */ + public static final int MAYBE = Constants.MAYBE; + + private static int checkSuperinterfacesContain(ClassHierarchyProvider hierarchy, String t1, String t2, HashSet visited) { + String[] ifaces = hierarchy.getSuperInterfaces(t1); + if (ifaces == null) { + return MAYBE; + } + + int r = NO; + for (int i = 0; i < ifaces.length; i++) { + String iface = ifaces[i]; + if (!visited.contains(iface)) { + visited.add(iface); + if (iface.equals(t2)) { + return YES; + } else { + int v = checkSuperinterfacesContain(hierarchy, iface, t2, visited); + if (v == YES) { + return YES; + } else if (v == MAYBE) { + r = MAYBE; + } + } + } + } + return r; + } + + private static int checkSupertypesContain(ClassHierarchyProvider hierarchy, String t1, String t2) { + int r = NO; + + String c = t1; + while (true) { + String sup = hierarchy.getSuperClass(c); + if (sup == null) { + if (!c.equals(Constants.TYPE_Object)) { + r = MAYBE; + } + break; + } + + if (sup.equals(t2)) { + return YES; + } + + c = sup; + } + + if (hierarchy.isInterface(t2) != NO) { + HashSet visited = new HashSet(); + + for (c = t1; c != null; c = hierarchy.getSuperClass(c)) { + int v = checkSuperinterfacesContain(hierarchy, c, t2, visited); + if (v == YES) { + return YES; + } else if (v == MAYBE) { + r = MAYBE; + } + } + } + + return r; + } + + private static int checkSubtypesContain(ClassHierarchyProvider hierarchy, String t1, String t2, HashSet visited) { + // No interface is a subclass of a real class + if (hierarchy.isInterface(t1) == NO && hierarchy.isInterface(t2) == YES) { + return NO; + } + + String[] subtypes = hierarchy.getSubClasses(t1); + if (subtypes == null) { + return MAYBE; + } + + int r = NO; + for (int i = 0; i < subtypes.length; i++) { + String subt = subtypes[i]; + if (!visited.contains(subt)) { + visited.add(subt); + if (subt.equals(t2)) { + return YES; + } else { + int v = checkSubtypesContain(hierarchy, subt, t2, visited); + if (v == YES) { + return YES; + } else if (v == MAYBE) { + r = MAYBE; + } + } + } + } + return r; + } + + private static int checkSubtypeOfHierarchy(ClassHierarchyProvider hierarchy, String t1, String t2) { + if (t2.equals(Constants.TYPE_Object)) { + return YES; + } else { + int v = checkSupertypesContain(hierarchy, t1, t2); + if (v == MAYBE) { + v = checkSubtypesContain(hierarchy, t2, t1, new HashSet()); + } + return v; + } + } + + /** + * Perform subtype check. + * + * @param hierarchy + * the hierarchy information to use for the decision + * @param t1 + * a type in JVM format + * @param t2 + * a type in JVM format + * @return whether t1 is a subtype of t2 (YES, NO, MAYBE) + */ + public static int isSubtypeOf(ClassHierarchyProvider hierarchy, String t1, String t2) { + if (t1 == null || t2 == null) { + return NO; + } else if (t1.equals(t2)) { + return YES; + } else if (t1.equals(Constants.TYPE_unknown) || t2.equals(Constants.TYPE_unknown)) { + return MAYBE; + } else { + switch (t1.charAt(0)) { + case 'L': + if (t1.equals(Constants.TYPE_null)) { + return YES; + } else if (t2.startsWith("[")) { + return NO; + } else if (hierarchy == null) { + return MAYBE; + } else { + return checkSubtypeOfHierarchy(hierarchy, t1, t2); + } + case '[': + if (t2.equals(Constants.TYPE_Object) || t2.equals("Ljava/io/Serializable;") || t2.equals("Ljava/lang/Cloneable;")) { + return YES; + } else if (t2.startsWith("[")) { + return isSubtypeOf(hierarchy, t1.substring(1), t2.substring(1)); + } else { + return NO; + } + default: + return NO; + } + } + } + + private static boolean insertSuperInterfaces(ClassHierarchyProvider hierarchy, String t, HashSet supers) { + String[] ifaces = hierarchy.getSuperInterfaces(t); + if (ifaces == null) { + return false; + } else { + boolean r = true; + for (int i = 0; i < ifaces.length; i++) { + String iface = ifaces[i]; + if (!supers.contains(iface)) { + supers.add(iface); + if (!insertSuperInterfaces(hierarchy, ifaces[i], supers)) { + r = false; + } + } + } + return r; + } + } + + private static boolean insertSuperClasses(ClassHierarchyProvider hierarchy, String t, HashSet supers) { + String last = t; + + for (String c = t; c != null; c = hierarchy.getSuperClass(c)) { + supers.add(c); + last = c; + } + + return last.equals(Constants.TYPE_Object); + } + + private static boolean insertSuperClassInterfaces(ClassHierarchyProvider hierarchy, String t, HashSet supers) { + boolean r = true; + + for (String c = t; c != null; c = hierarchy.getSuperClass(c)) { + if (!insertSuperInterfaces(hierarchy, c, supers)) { + r = false; + } + } + + return r; + } + + private static boolean collectDominatingSuperClasses(ClassHierarchyProvider hierarchy, String t, HashSet matches, HashSet supers) { + String last = t; + + for (String c = t; c != null; c = hierarchy.getSuperClass(c)) { + if (matches.contains(c)) { + supers.add(c); + return true; + } + last = c; + } + + return last.equals(Constants.TYPE_Object); + } + + private static boolean collectDominatingSuperInterfacesFromClass(ClassHierarchyProvider hierarchy, String t, HashSet matches, + HashSet supers) { + String[] ifaces = hierarchy.getSuperInterfaces(t); + if (ifaces == null) { + return false; + } else { + boolean r = true; + for (int i = 0; i < ifaces.length; i++) { + String iface = ifaces[i]; + if (!supers.contains(iface)) { + supers.add(iface); + if (!insertSuperInterfaces(hierarchy, ifaces[i], supers)) { + r = false; + } + } + } + return r; + } + } + + private static boolean collectDominatingSuperInterfaces(ClassHierarchyProvider hierarchy, String t, HashSet matches, + HashSet supers) { + boolean r = true; + + for (String c = t; c != null && !supers.contains(c); c = hierarchy.getSuperClass(c)) { + if (!collectDominatingSuperInterfacesFromClass(hierarchy, c, matches, supers)) { + r = false; + } + } + + return r; + } + + private static String findCommonSupertypeHierarchy(ClassHierarchyProvider hierarchy, String t1, String t2) { + if (isSubtypeOf(hierarchy, t1, t2) == YES) { + return t2; + } else if (isSubtypeOf(hierarchy, t2, t1) == YES) { + return t1; + } + + HashSet t1Supers = new HashSet(); + t1Supers.add(Constants.TYPE_Object); + boolean t1ExactClasses = insertSuperClasses(hierarchy, t1, t1Supers); + int t1ClassCount = t1Supers.size(); + boolean t1ExactInterfaces = insertSuperClassInterfaces(hierarchy, t1, t1Supers); + + HashSet t2Supers = new HashSet(); + boolean t2ExactClasses = collectDominatingSuperClasses(hierarchy, t2, t1Supers, t2Supers); + + if (t2Supers.size() == 0) { + // we didn't find a common superclass, so we don't know what it might be + return Constants.TYPE_unknown; + } // otherwise we know for sure what the common superclass is + + boolean t2ExactInterfaces; + if (t1ExactInterfaces && t1ExactClasses && t1Supers.size() - t1ClassCount == 0) { + // t1 doesn't have any interfaces so we don't need to search t2's + // interfaces + t2ExactInterfaces = true; + } else { + t2ExactInterfaces = collectDominatingSuperInterfaces(hierarchy, t2, t1Supers, t2Supers); + if (!t1ExactInterfaces && t2Supers.size() != 1) { + // we found an interface; it might also apply to t1; must bail + return Constants.TYPE_unknown; + } + } + + if (!t2ExactClasses || !t2ExactInterfaces) { + // there may be some common interfaces that we don't know about + return ""; + } + + for (Iterator iter = t2Supers.iterator(); iter.hasNext();) { + String element = iter.next(); + boolean subsumed = false; + + for (Iterator iterator = t2Supers.iterator(); iterator.hasNext();) { + String element2 = iterator.next(); + if (element != element2 && isSubtypeOf(hierarchy, element2, element) == YES) { + subsumed = true; + break; + } + } + + if (subsumed) { + iter.remove(); + } + } + + if (t2Supers.size() == 1) { + return t2Supers.iterator().next(); + } else if (t2Supers.size() == 0) { + return Constants.TYPE_Object; + } else { + return Constants.TYPE_unknown; // some non-representable combination of + // class and interfaces + } + } + + /** + * Compute the most specific common supertype. + * + * @param hierarchy + * the hierarchy information to use for the decision + * @param t1 + * a type in JVM format + * @param t2 + * a type in JVM format + * @return the most specific common supertype of t1 and t2, or TYPE_unknown if + * it cannot be determined or cannot be represented as a Java type, or + * null if there is no common supertype + */ + public static String findCommonSupertype(ClassHierarchyProvider hierarchy, String t1, String t2) { + if (t1 == null || t2 == null) { + return null; + } else if (t1.equals(t2)) { + return t1; + } else if (t1.equals(Constants.TYPE_unknown) || t2.equals(Constants.TYPE_unknown)) { + return Constants.TYPE_unknown; + } else { + if (t2.charAt(0) == '[') { // put array into t1 + String t = t1; + t1 = t2; + t2 = t; + } + + switch (t1.charAt(0)) { + case 'L': + // two non-array types + // if either one is constant null, return the other one + if (t1.equals(Constants.TYPE_null)) { + return t2; + } else if (t2.equals(Constants.TYPE_null)) { + return t1; + } else if (hierarchy == null) { + // don't have a class hierarchy + return Constants.TYPE_unknown; + } else { + return findCommonSupertypeHierarchy(hierarchy, t1, t2); + } + case '[': { + char ch2 = t2.charAt(0); + if (ch2 == '[') { + char ch1_1 = t1.charAt(1); + if (ch1_1 == '[' || ch1_1 == 'L') { + return "[" + findCommonSupertype(hierarchy, t1.substring(1), t2.substring(1)); + } else { + return Constants.TYPE_Object; + } + } else if (ch2 == 'L') { + if (t2.equals(Constants.TYPE_null)) { + return t1; + } else if (t2.equals("Ljava/io/Serializable;") || t2.equals("Ljava/lang/Cloneable;")) { + return t2; + } else { + return Constants.TYPE_Object; + } + } else { + return null; + } + } + default: + return null; + } + } + } +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/analysis/ClassHierarchyProvider.java b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/analysis/ClassHierarchyProvider.java new file mode 100644 index 000000000..d618beece --- /dev/null +++ b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/analysis/ClassHierarchyProvider.java @@ -0,0 +1,42 @@ +/******************************************************************************* + * 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.shrikeBT.analysis; + +/** + * This interface provides information about the class hierarchy to some + * consumer, such as a bytecode verifier. + * + * All class names are given in JVM type format, e.g., Ljava/lang/Object;. + */ +public interface ClassHierarchyProvider { + /** + * @return the superclass of the given class, or null if the superclass is not + * known or cl is java.lang.Object + */ + public String getSuperClass(String cl); + + /** + * @return the superinterfaces of the given class, or null if they are not + * known + */ + public String[] getSuperInterfaces(String cl); + + /** + * @return the complete set of direct subclasses or implementors of cl, or + * null if the complete set is not known + */ + public String[] getSubClasses(String cl); + + /** + * @return whether or not cl is an interface, or Constants.MAYBE if not known + */ + public int isInterface(String cl); +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/analysis/ClassHierarchyStore.java b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/analysis/ClassHierarchyStore.java new file mode 100644 index 000000000..bca99ca06 --- /dev/null +++ b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/analysis/ClassHierarchyStore.java @@ -0,0 +1,114 @@ +/******************************************************************************* + * 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.shrikeBT.analysis; + +import java.util.HashMap; +import java.util.Iterator; + +import com.ibm.wala.shrikeBT.Constants; + +/** + * This implementation of ClassHierarchyProvider is a simple writable data + * structure representing a class hierarchy. You call setClassInfo to record + * information about a class. + */ +public final class ClassHierarchyStore implements ClassHierarchyProvider { + private static final String[] noClasses = new String[0]; + + final static class ClassInfo { + boolean isInterface; + boolean isFinal; + String superClass; + String[] superInterfaces; + + ClassInfo(boolean isInterface, boolean isFinal, String superClass, String[] superInterfaces) { + this.isInterface = isInterface; + this.isFinal = isFinal; + this.superClass = superClass; + this.superInterfaces = superInterfaces; + } + } + + private HashMap contents = new HashMap(); + + /** + * Create an empty store. + */ + public ClassHierarchyStore() { + } + + /** + * Append some class information to the store. + * + * @param cl + * the JVM type of the class being added (e.g., Ljava/lang/Object;) + * @param isInterface + * true iff it's an interface + * @param isFinal + * true iff it's final + * @param superClass + * the JVM type of the superclass, or null if this is Object + * @param superInterfaces + * the JVM types of its implemented interfaces + */ + public void setClassInfo(String cl, boolean isInterface, boolean isFinal, String superClass, String[] superInterfaces) { + if (superClass != null && superClass.equals(cl)) { + throw new Error("Class " + cl + " cannot be its own superclass"); + } + contents.put(cl, new ClassInfo(isInterface, isFinal, superClass, superInterfaces)); + } + + /** + * Delete the class information from the store. + */ + public void removeClassInfo(String cl) { + contents.remove(cl); + } + + /** + * Iterate through all classes in the store. + */ + public Iterator iterateOverClasses() { + return contents.keySet().iterator(); + } + + /** + * @see ClassHierarchyProvider#getSuperClass(String) + */ + public String getSuperClass(String cl) { + ClassInfo info = contents.get(cl); + return info == null ? null : info.superClass; + } + + /* + * @see ClassHierarchyProvider#getSuperInterfaces(String) + */ + public String[] getSuperInterfaces(String cl) { + ClassInfo info = contents.get(cl); + return info == null ? null : info.superInterfaces; + } + + /* + * @see ClassHierarchyProvider#getSubClasses(String) + */ + public String[] getSubClasses(String cl) { + ClassInfo info = contents.get(cl); + return (info == null || !info.isFinal) ? null : noClasses; + } + + /* + * @see ClassHierarchyProvider#isInterface(String) + */ + public int isInterface(String cl) { + ClassInfo info = contents.get(cl); + return info == null ? Constants.MAYBE : (info.isInterface ? Constants.YES : Constants.NO); + } +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/analysis/Verifier.java b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/analysis/Verifier.java new file mode 100644 index 000000000..2651ad901 --- /dev/null +++ b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/analysis/Verifier.java @@ -0,0 +1,298 @@ +/******************************************************************************* + * 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.shrikeBT.analysis; + +import java.util.BitSet; +import java.util.List; + +import com.ibm.wala.shrikeBT.ArrayLengthInstruction; +import com.ibm.wala.shrikeBT.ArrayLoadInstruction; +import com.ibm.wala.shrikeBT.ArrayStoreInstruction; +import com.ibm.wala.shrikeBT.BinaryOpInstruction; +import com.ibm.wala.shrikeBT.CheckCastInstruction; +import com.ibm.wala.shrikeBT.ComparisonInstruction; +import com.ibm.wala.shrikeBT.ConditionalBranchInstruction; +import com.ibm.wala.shrikeBT.ConstantInstruction; +import com.ibm.wala.shrikeBT.Constants; +import com.ibm.wala.shrikeBT.ConversionInstruction; +import com.ibm.wala.shrikeBT.DupInstruction; +import com.ibm.wala.shrikeBT.ExceptionHandler; +import com.ibm.wala.shrikeBT.GetInstruction; +import com.ibm.wala.shrikeBT.GotoInstruction; +import com.ibm.wala.shrikeBT.InstanceofInstruction; +import com.ibm.wala.shrikeBT.Instruction; +import com.ibm.wala.shrikeBT.InvokeInstruction; +import com.ibm.wala.shrikeBT.LoadInstruction; +import com.ibm.wala.shrikeBT.MethodData; +import com.ibm.wala.shrikeBT.MonitorInstruction; +import com.ibm.wala.shrikeBT.NewInstruction; +import com.ibm.wala.shrikeBT.PopInstruction; +import com.ibm.wala.shrikeBT.PutInstruction; +import com.ibm.wala.shrikeBT.ReturnInstruction; +import com.ibm.wala.shrikeBT.ShiftInstruction; +import com.ibm.wala.shrikeBT.StoreInstruction; +import com.ibm.wala.shrikeBT.SwitchInstruction; +import com.ibm.wala.shrikeBT.ThrowInstruction; +import com.ibm.wala.shrikeBT.UnaryOpInstruction; +import com.ibm.wala.shrikeBT.Util; + +/** + * This class typechecks intermediate code. It's very easy to use: + * + *
                              + * 
                              + *      MethodData md = ...;
                              + *      try {
                              + *          (new Verifier(md)).verify();
                              + *      } catch (Verifier.FailureException ex) {
                              + *          System.out.println("Verification failed at instruction "
                              + *              + ex.getOffset() + ": " + ex.getReason());
                              + *      }
                              + *  
                              + * 
                              + * + * For full verification you need to provide class hierarchy information using + * setClassHierarchy. Without this information, we can't compute the exact types + * of variables at control flow merge points. If you don't provide a hierarchy, + * or the hierarchy you provide is partial, then the Verifier will be + * optimistic. + * + * This method can also be used to gather type information for every stack and + * local variable at every program point. Just call computeTypes() instead of + * verify() and then retrieve the results with getLocalTypes() and + * getStackTypes(). + */ +public final class Verifier extends Analyzer { + final class VerifyVisitor extends TypeVisitor { + private int curIndex; + private List curPath; + private FailureException ex; + private String[] curStack; + private String[] curLocals; + + VerifyVisitor() { + } + + public void setState(int offset, List path, String[] curStack, String[] curLocals) { + curIndex = offset; + curPath = path; + this.curStack = curStack; + this.curLocals = curLocals; + } + + public boolean shouldContinue() { + return ex == null; + } + + void checkError() throws FailureException { + if (ex != null) { + throw ex; + } + } + + private void checkStackSubtype(int i, String t) { + if (!isSubtypeOf(curStack[i], Util.getStackType(t))) { + ex = new FailureException(curIndex, "Expected type " + t + " at stack " + i + ", got " + curStack[i], curPath); + } + } + + private void checkArrayStackSubtype(int i, String t) { + if (!t.equals(Constants.TYPE_byte) || !"[Z".equals(curStack[i])) { + checkStackSubtype(i, Util.makeArray(t)); + } + } + + public void visitConstant(ConstantInstruction instruction) { + // make sure that constants are checked + instruction.getValue(); + } + + public void visitGoto(GotoInstruction instruction) { + } + + public void visitLocalLoad(LoadInstruction instruction) { + String t = curLocals[instruction.getVarIndex()]; + if (t == null) { + ex = new FailureException(curIndex, "Local variable " + instruction.getVarIndex() + " is not defined", curPath); + } + if (!isSubtypeOf(t, instruction.getType())) { + ex = new FailureException(curIndex, "Expected type " + instruction.getType() + " for local " + instruction.getVarIndex() + + ", got " + t, curPath); + } + } + + public void visitLocalStore(StoreInstruction instruction) { + checkStackSubtype(0, instruction.getType()); + } + + public void visitArrayLoad(ArrayLoadInstruction instruction) { + checkStackSubtype(0, Constants.TYPE_int); + checkArrayStackSubtype(1, instruction.getType()); + } + + public void visitArrayStore(ArrayStoreInstruction instruction) { + checkStackSubtype(0, instruction.getType()); + checkStackSubtype(1, Constants.TYPE_int); + checkArrayStackSubtype(2, instruction.getType()); + } + + public void visitPop(PopInstruction instruction) { + } + + public void visitDup(DupInstruction instruction) { + } + + public void visitBinaryOp(BinaryOpInstruction instruction) { + checkStackSubtype(0, instruction.getType()); + checkStackSubtype(1, instruction.getType()); + } + + public void visitUnaryOp(UnaryOpInstruction instruction) { + checkStackSubtype(0, instruction.getType()); + } + + public void visitShift(ShiftInstruction instruction) { + checkStackSubtype(0, Constants.TYPE_int); + checkStackSubtype(1, instruction.getType()); + } + + public void visitConversion(ConversionInstruction instruction) { + checkStackSubtype(0, instruction.getFromType()); + } + + public void visitComparison(ComparisonInstruction instruction) { + checkStackSubtype(0, instruction.getType()); + checkStackSubtype(1, instruction.getType()); + } + + public void visitConditionalBranch(ConditionalBranchInstruction instruction) { + checkStackSubtype(0, instruction.getType()); + checkStackSubtype(1, instruction.getType()); + } + + public void visitSwitch(SwitchInstruction instruction) { + checkStackSubtype(0, Constants.TYPE_int); + } + + public void visitReturn(ReturnInstruction instruction) { + if (instruction.getType() != Constants.TYPE_void) { + checkStackSubtype(0, instruction.getType()); + checkStackSubtype(0, Util.getReturnType(signature)); + } + } + + public void visitGet(GetInstruction instruction) { + // make sure constant pool entries are dereferenced + String classType = instruction.getClassType(); + + if (!instruction.isStatic()) { + checkStackSubtype(0, classType); + } + } + + public void visitPut(PutInstruction instruction) { + // make sure constant pool entries are dereferenced + String classType = instruction.getClassType(); + String type = instruction.getFieldType(); + + checkStackSubtype(0, type); + if (!instruction.isStatic()) { + checkStackSubtype(1, classType); + } + } + + public void visitInvoke(InvokeInstruction instruction) { + // make sure constant pool entries are dereferenced + String classType = instruction.getClassType(); + String signature = instruction.getMethodSignature(); + + String thisClass = instruction.getInvocationMode() == Constants.OP_invokestatic ? null : classType; + String[] params = Util.getParamsTypes(thisClass, signature); + + for (int i = 0; i < params.length; i++) { + checkStackSubtype(i, params[params.length - 1 - i]); + } + } + + public void visitNew(NewInstruction instruction) { + for (int i = 0; i < instruction.getArrayBoundsCount(); i++) { + checkStackSubtype(i, Constants.TYPE_int); + } + // make sure constant is dereferenced + instruction.getType(); + } + + public void visitArrayLength(ArrayLengthInstruction instruction) { + if (!curStack[0].equals(Constants.TYPE_null) && !Util.isArrayType(curStack[0])) { + ex = new FailureException(curIndex, "Expected array type at stack 0, got " + curStack[0], curPath); + } + } + + public void visitThrow(ThrowInstruction instruction) { + checkStackSubtype(0, Constants.TYPE_Throwable); + } + + public void visitMonitor(MonitorInstruction instruction) { + checkStackSubtype(0, Constants.TYPE_Object); + } + + public void visitCheckCast(CheckCastInstruction instruction) { + checkStackSubtype(0, Constants.TYPE_Object); + // make sure constant is dereferenced + instruction.getType(); + } + + public void visitInstanceof(InstanceofInstruction instruction) { + checkStackSubtype(0, Constants.TYPE_Object); + // make sure constant is dereferenced + instruction.getType(); + } + } + + /** + * Initialize a verifier. + */ + public Verifier(boolean isStatic, String classType, String signature, Instruction[] instructions, ExceptionHandler[][] handlers) { + super(isStatic, classType, signature, instructions, handlers); + } + + /** + * Initialize a verifier. + */ + public Verifier(MethodData info) { + super(info); + } + + /** + * Try to verify the method. If verification is unsuccessful, we throw an + * exception. + * + * @throws FailureException + * the method contains invalid bytecode + */ + public void verify() throws FailureException { + VerifyVisitor v = new VerifyVisitor(); + computeTypes(v, getBasicBlockStarts(), true); + v.checkError(); + } + + public void verifyCollectAll() throws FailureException { + VerifyVisitor v = new VerifyVisitor(); + BitSet all = new BitSet(instructions.length); + all.set(0, instructions.length); + computeTypes(v, all, true); + v.checkError(); + } + + public void computeTypes() throws FailureException { + computeTypes(null, getBasicBlockStarts(), false); + } +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/info/InstructionTypeCounter.java b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/info/InstructionTypeCounter.java new file mode 100644 index 000000000..b841ed8e1 --- /dev/null +++ b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/info/InstructionTypeCounter.java @@ -0,0 +1,349 @@ +/******************************************************************************* + * 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.shrikeBT.info; + +import com.ibm.wala.shrikeBT.ArrayLengthInstruction; +import com.ibm.wala.shrikeBT.ArrayLoadInstruction; +import com.ibm.wala.shrikeBT.ArrayStoreInstruction; +import com.ibm.wala.shrikeBT.BinaryOpInstruction; +import com.ibm.wala.shrikeBT.CheckCastInstruction; +import com.ibm.wala.shrikeBT.ComparisonInstruction; +import com.ibm.wala.shrikeBT.ConditionalBranchInstruction; +import com.ibm.wala.shrikeBT.ConstantInstruction; +import com.ibm.wala.shrikeBT.ConversionInstruction; +import com.ibm.wala.shrikeBT.DupInstruction; +import com.ibm.wala.shrikeBT.ExceptionHandler; +import com.ibm.wala.shrikeBT.GetInstruction; +import com.ibm.wala.shrikeBT.GotoInstruction; +import com.ibm.wala.shrikeBT.InstanceofInstruction; +import com.ibm.wala.shrikeBT.Instruction; +import com.ibm.wala.shrikeBT.InvokeInstruction; +import com.ibm.wala.shrikeBT.LoadInstruction; +import com.ibm.wala.shrikeBT.MethodData; +import com.ibm.wala.shrikeBT.MonitorInstruction; +import com.ibm.wala.shrikeBT.NewInstruction; +import com.ibm.wala.shrikeBT.PopInstruction; +import com.ibm.wala.shrikeBT.PutInstruction; +import com.ibm.wala.shrikeBT.ReturnInstruction; +import com.ibm.wala.shrikeBT.ShiftInstruction; +import com.ibm.wala.shrikeBT.StoreInstruction; +import com.ibm.wala.shrikeBT.SwapInstruction; +import com.ibm.wala.shrikeBT.SwitchInstruction; +import com.ibm.wala.shrikeBT.ThrowInstruction; +import com.ibm.wala.shrikeBT.UnaryOpInstruction; + +/** + * This method annotation counts the number of instructions of each type + * (according to each Instruction subclass). + * + * The get...Count methods are the only methods needed by clients. These methods + * check to see if the MethodData object already has an InstructionTypeCounter + * annotation before recomputing the counts and returning the desired count. + */ +public class InstructionTypeCounter implements MethodData.Results { + private final static String key = InstructionTypeCounter.class.getName(); + + private int countMonitors; + private int countGets; + private int countPuts; + private int countArrayLoads; + private int countArrayStores; + private int countInvokes; + private int countArrayLengths; + private int countBinaryOps; + private int countCheckCasts; + private int countComparisons; + private int countConditionalBranches; + private int countConstants; + private int countConversions; + private int countDups; + private int countGotos; + private int countInstanceOfs; + private int countLocalLoads; + private int countLocalStores; + private int countNews; + private int countPops; + private int countReturns; + private int countShifts; + private int countSwaps; + private int countSwitches; + private int countThrows; + private int countUnaryOps; + + InstructionTypeCounter(MethodData info) { + recalculateFrom(info.getInstructions()); + } + + private void recalculateFrom(Instruction[] instructions) { + countMonitors = 0; + countGets = 0; + countPuts = 0; + countArrayLoads = 0; + countArrayStores = 0; + countInvokes = 0; + countArrayLengths = 0; + countBinaryOps = 0; + countCheckCasts = 0; + countComparisons = 0; + countConditionalBranches = 0; + countConstants = 0; + countConversions = 0; + countDups = 0; + countGotos = 0; + countInstanceOfs = 0; + countLocalLoads = 0; + countLocalStores = 0; + countNews = 0; + countPops = 0; + countReturns = 0; + countShifts = 0; + countSwaps = 0; + countSwitches = 0; + countThrows = 0; + countUnaryOps = 0; + + Instruction.Visitor visitor = new Instruction.Visitor() { + public void visitArrayLength(ArrayLengthInstruction instruction) { + countArrayLengths++; + } + + public void visitBinaryOp(BinaryOpInstruction instruction) { + countBinaryOps++; + } + + public void visitCheckCast(CheckCastInstruction instruction) { + countCheckCasts++; + } + + public void visitComparison(ComparisonInstruction instruction) { + countComparisons++; + } + + public void visitConditionalBranch(ConditionalBranchInstruction instruction) { + countConditionalBranches++; + } + + public void visitConstant(ConstantInstruction instruction) { + countConstants++; + } + + public void visitConversion(ConversionInstruction instruction) { + countConversions++; + } + + public void visitDup(DupInstruction instruction) { + countDups++; + } + + public void visitGoto(GotoInstruction instruction) { + countGotos++; + } + + public void visitInstanceof(InstanceofInstruction instruction) { + countInstanceOfs++; + } + + public void visitLocalLoad(LoadInstruction instruction) { + countLocalLoads++; + } + + public void visitLocalStore(StoreInstruction instruction) { + countLocalStores++; + } + + public void visitNew(NewInstruction instruction) { + countNews++; + } + + public void visitPop(PopInstruction instruction) { + countPops++; + } + + public void visitReturn(ReturnInstruction instruction) { + countReturns++; + } + + public void visitShift(ShiftInstruction instruction) { + countShifts++; + } + + public void visitSwap(SwapInstruction instruction) { + countSwaps++; + } + + public void visitSwitch(SwitchInstruction instruction) { + countSwitches++; + } + + public void visitThrow(ThrowInstruction instruction) { + countThrows++; + } + + public void visitUnaryOp(UnaryOpInstruction instruction) { + countUnaryOps++; + } + + public void visitArrayLoad(ArrayLoadInstruction instruction) { + countArrayLoads++; + } + + public void visitArrayStore(ArrayStoreInstruction instruction) { + countArrayStores++; + } + + public void visitGet(GetInstruction instruction) { + countGets++; + } + + public void visitPut(PutInstruction instruction) { + countPuts++; + } + + public void visitMonitor(MonitorInstruction instruction) { + countMonitors++; + } + + public void visitInvoke(InvokeInstruction instruction) { + countInvokes++; + } + }; + + for (int i = 0; i < instructions.length; i++) { + instructions[i].visit(visitor); + } + } + + /** + * Whenever the underlying method is updated, we'll throw away our counts so + * they can be reconstructed from scratch next time. + * + * This is not to be called by clients. + */ + public boolean notifyUpdate(MethodData info, Instruction[] newInstructions, ExceptionHandler[][] newHandlers, + int[] newInstructionMap) { + // just throw this away and we'll recalculate from scratch if necessary + return true; + } + + public static int getArrayLoadCount(MethodData info) { + return getCounter(info).countArrayLoads; + } + + public static int getArrayStoreCount(MethodData info) { + return getCounter(info).countArrayStores; + } + + public static int getGetCount(MethodData info) { + return getCounter(info).countGets; + } + + public static int getPutCount(MethodData info) { + return getCounter(info).countPuts; + } + + public static int getMonitorCount(MethodData info) { + return getCounter(info).countMonitors; + } + + public static int getInvokeCount(MethodData info) { + return getCounter(info).countInvokes; + } + + public static int getComparisonCount(MethodData info) { + return getCounter(info).countComparisons; + } + + public static int getArrayLengthCount(MethodData info) { + return getCounter(info).countArrayLengths; + } + + public static int getConstantCount(MethodData info) { + return getCounter(info).countConstants; + } + + public static int getShiftCount(MethodData info) { + return getCounter(info).countShifts; + } + + public static int getSwitchesCount(MethodData info) { + return getCounter(info).countSwitches; + } + + public static int getSwapCount(MethodData info) { + return getCounter(info).countSwaps; + } + + public static int getBinaryOpCount(MethodData info) { + return getCounter(info).countBinaryOps; + } + + public static int getCheckCastCount(MethodData info) { + return getCounter(info).countCheckCasts; + } + + public static int getThrowCount(MethodData info) { + return getCounter(info).countThrows; + } + + public static int getConditionalBranchCount(MethodData info) { + return getCounter(info).countConditionalBranches; + } + + public static int getConversionCount(MethodData info) { + return getCounter(info).countConversions; + } + + public static int getDupCount(MethodData info) { + return getCounter(info).countDups; + } + + public static int getGotoCount(MethodData info) { + return getCounter(info).countGotos; + } + + public static int getReturnCount(MethodData info) { + return getCounter(info).countReturns; + } + + public static int getInstanceOfCount(MethodData info) { + return getCounter(info).countInstanceOfs; + } + + public static int getLocalLoadCount(MethodData info) { + return getCounter(info).countLocalLoads; + } + + public static int getLocalStoreCount(MethodData info) { + return getCounter(info).countLocalStores; + } + + public static int getNewCount(MethodData info) { + return getCounter(info).countNews; + } + + public static int getPopCount(MethodData info) { + return getCounter(info).countPops; + } + + public static int getUnaryOpCount(MethodData info) { + return getCounter(info).countUnaryOps; + } + + private static InstructionTypeCounter getCounter(MethodData info) { + InstructionTypeCounter c = (InstructionTypeCounter) info.getInfo(key); + if (c == null) { + c = new InstructionTypeCounter(info); + info.putInfo(key, c); + } + + return c; + } +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/info/LocalAllocator.java b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/info/LocalAllocator.java new file mode 100644 index 000000000..ffc27fbe7 --- /dev/null +++ b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/info/LocalAllocator.java @@ -0,0 +1,98 @@ +/******************************************************************************* + * 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.shrikeBT.info; + +import com.ibm.wala.shrikeBT.ExceptionHandler; +import com.ibm.wala.shrikeBT.Instruction; +import com.ibm.wala.shrikeBT.LoadInstruction; +import com.ibm.wala.shrikeBT.MethodData; +import com.ibm.wala.shrikeBT.StoreInstruction; +import com.ibm.wala.shrikeBT.Util; + +/** + * This method annotation parcels out fresh local variables for use as + * temporaries by instrumentation code. It assumes that local variables are not + * allocated by any other mechanism. + */ +public class LocalAllocator implements MethodData.Results { + private final static String key = LocalAllocator.class.getName(); + + private int nextLocal; + + LocalAllocator(MethodData info) { + recalculateFrom(info); + } + + private void recalculateFrom(MethodData info) { + Instruction[] instructions = info.getInstructions(); + final int[] max = { Util.getParamsWordSize(info.getSignature()) + (info.getIsStatic() ? 0 : 1) }; + + Instruction.Visitor visitor = new Instruction.Visitor() { + public void visitLocalLoad(LoadInstruction instruction) { + int v = instruction.getVarIndex() + Util.getWordSize(instruction.getType()); + if (v > max[0]) { + max[0] = v; + } + } + + public void visitLocalStore(StoreInstruction instruction) { + int v = instruction.getVarIndex() + Util.getWordSize(instruction.getType()); + if (v > max[0]) { + max[0] = v; + } + } + }; + + for (int i = 0; i < instructions.length; i++) { + instructions[i].visit(visitor); + } + + nextLocal = max[0]; + } + + private int allocateLocals(int count) { + int r = nextLocal; + nextLocal += count; + return r; + } + + /** + * This should not be called by clients. + */ + public boolean notifyUpdate(MethodData info, Instruction[] newInstructions, ExceptionHandler[][] newHandlers, + int[] newInstructionMap) { + return false; + } + + /** + * Allocates a new local variable of the specified type. + */ + public static int allocate(MethodData info, int count) { + LocalAllocator l = (LocalAllocator) info.getInfo(key); + if (l == null) { + l = new LocalAllocator(info); + info.putInfo(key, l); + } + + return l.allocateLocals(count); + } + + public static int allocate(MethodData info, String type) { + return allocate(info, type == null ? 2 : Util.getWordSize(type)); + } + + /** + * Allocates a new local that will fit any type. + */ + public static int allocate(MethodData info) { + return allocate(info, null); + } +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/info/ThisAssignmentChecker.java b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/info/ThisAssignmentChecker.java new file mode 100644 index 000000000..9425579d9 --- /dev/null +++ b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/info/ThisAssignmentChecker.java @@ -0,0 +1,70 @@ +/******************************************************************************* + * 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.shrikeBT.info; + +import com.ibm.wala.shrikeBT.ExceptionHandler; +import com.ibm.wala.shrikeBT.Instruction; +import com.ibm.wala.shrikeBT.MethodData; +import com.ibm.wala.shrikeBT.StoreInstruction; + +/** + * This method annotation checks to see whether "this" is assigned to by the + * method. The result is cached in an annotation. + */ +public class ThisAssignmentChecker implements MethodData.Results { + private final static String key = ThisAssignmentChecker.class.getName(); + + private boolean assignmentToThis; + + ThisAssignmentChecker(MethodData info) { + recalculateFrom(info); + } + + private void recalculateFrom(MethodData info) { + assignmentToThis = false; + + if (!info.getIsStatic()) { + Instruction[] instructions = info.getInstructions(); + + for (int i = 0; i < instructions.length; i++) { + Instruction instr = instructions[i]; + if (instr instanceof StoreInstruction) { + StoreInstruction st = (StoreInstruction) instr; + if (st.getVarIndex() == 0) { + assignmentToThis = true; + } + } + } + } + } + + /** + * This should not be called by any client. + */ + public boolean notifyUpdate(MethodData info, Instruction[] newInstructions, ExceptionHandler[][] newHandlers, + int[] newInstructionMap) { + // just throw this away and we'll recalculate from scratch if necessary + return true; + } + + /** + * @return true iff 'this' is assigned to by the method + */ + public static boolean isThisAssigned(MethodData info) { + ThisAssignmentChecker c = (ThisAssignmentChecker) info.getInfo(key); + if (c == null) { + c = new ThisAssignmentChecker(info); + info.putInfo(key, c); + } + + return c.assignmentToThis; + } +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/shrikeCT/CTCompiler.java b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/shrikeCT/CTCompiler.java new file mode 100644 index 000000000..d6794f545 --- /dev/null +++ b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/shrikeCT/CTCompiler.java @@ -0,0 +1,88 @@ +/******************************************************************************* + * 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.shrikeBT.shrikeCT; + +import java.util.Random; + +import com.ibm.wala.shrikeBT.Compiler; +import com.ibm.wala.shrikeBT.MethodData; +import com.ibm.wala.shrikeCT.ClassWriter; + +/** + * This class lets you compile ShrikeBT intermediate code into real Java + * bytecodes using ShrikeCT. + */ +final public class CTCompiler extends Compiler { + private ClassWriter cw; + + /** + * Compile 'md' into the class given by 'cw'. + */ + public CTCompiler(ClassWriter cw, MethodData md) { + super(md); + this.cw = cw; + } + + protected int allocateConstantPoolInteger(int v) { + return cw.addCPInt(v); + } + + protected int allocateConstantPoolFloat(float v) { + return cw.addCPFloat(v); + } + + protected int allocateConstantPoolLong(long v) { + return cw.addCPLong(v); + } + + protected int allocateConstantPoolDouble(double v) { + return cw.addCPDouble(v); + } + + protected int allocateConstantPoolString(String v) { + return cw.addCPString(v); + } + + protected int allocateConstantPoolClassType(String c) { + return cw.addCPClass(convertTypeToClass(c)); + } + + /** + * Convert a JVM type to the internal JVM class name (e.g., Ljava/lang/Object; + * to java/lang/Object) + */ + public static String convertTypeToClass(String s) { + if (s.length() > 0 && s.charAt(0) == 'L') { + return s.substring(1, s.length() - 1); + } else { + return s; + } + } + + protected int allocateConstantPoolField(String c, String name, String type) { + return cw.addCPFieldRef(convertTypeToClass(c), name, type); + } + + protected int allocateConstantPoolMethod(String c, String name, String sig) { + return cw.addCPMethodRef(convertTypeToClass(c), name, sig); + } + + protected int allocateConstantPoolInterfaceMethod(String c, String name, String sig) { + return cw.addCPInterfaceMethodRef(convertTypeToClass(c), name, sig); + } + + protected String createHelperMethod(boolean isStatic, String sig) { + long r = Math.abs((new Random()).nextLong()); + String name = "_helper_" + r; + + return name; + } +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/shrikeCT/CTDecoder.java b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/shrikeCT/CTDecoder.java new file mode 100644 index 000000000..46406128c --- /dev/null +++ b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/shrikeCT/CTDecoder.java @@ -0,0 +1,149 @@ +/******************************************************************************* + * 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.shrikeBT.shrikeCT; + +import com.ibm.wala.shrikeBT.ConstantPoolReader; +import com.ibm.wala.shrikeBT.Decoder; +import com.ibm.wala.shrikeCT.ClassReader; +import com.ibm.wala.shrikeCT.CodeReader; +import com.ibm.wala.shrikeCT.ConstantPoolParser; +import com.ibm.wala.shrikeCT.InvalidClassFileException; + +/** + * This class decodes Java bytecodes into ShrikeBT code using a ShrikeCT class + * reader. + */ +final public class CTDecoder extends Decoder { + + /** + * Decode the code resource 'r'. + */ + public CTDecoder(CodeReader r) { + this(r, makeConstantPoolReader(r.getClassReader())); + } + + /** + * Decode the code resource 'r' using the predeclared constant pool reader + * 'cpr' (obtained by makeConstantPoolReader below). + */ + public CTDecoder(CodeReader r, ConstantPoolReader cpr) { + super(r.getBytecode(), r.getRawHandlers(), cpr); + } + + /** + * Convert the internal JVM class name to a JVM type name (e.g., + * java/lang/Object to Ljava/lang/Object;). + */ + public static String convertClassToType(String s) { + if (s.length() > 0 && s.charAt(0) != '[') { + return "L" + s + ";"; + } else { + return s; + } + } + + /** + * Build a ConstantPoolReader implementation to read the constant pool from + * 'cr'. + */ + public static ConstantPoolReader makeConstantPoolReader(ClassReader cr) { + return new CPReader(cr.getCP()); + } + + final static class CPReader extends ConstantPoolReader { + private ConstantPoolParser cp; + + CPReader(ConstantPoolParser cp) { + this.cp = cp; + } + + public int getConstantPoolItemType(int index) { + return cp.getItemType(index); + } + + private Error convertToError(InvalidClassFileException e) { + e.printStackTrace(); + return new Error("Invalid class file: " + e.getMessage()); + } + + public int getConstantPoolInteger(int index) { + try { + return cp.getCPInt(index); + } catch (InvalidClassFileException e) { + throw convertToError(e); + } + } + + public float getConstantPoolFloat(int index) { + try { + return cp.getCPFloat(index); + } catch (InvalidClassFileException e) { + throw convertToError(e); + } + } + + public long getConstantPoolLong(int index) { + try { + return cp.getCPLong(index); + } catch (InvalidClassFileException e) { + throw convertToError(e); + } + } + + public double getConstantPoolDouble(int index) { + try { + return cp.getCPDouble(index); + } catch (InvalidClassFileException e) { + throw convertToError(e); + } + } + + public String getConstantPoolString(int index) { + try { + return cp.getCPString(index); + } catch (InvalidClassFileException e) { + throw convertToError(e); + } + } + + public String getConstantPoolClassType(int index) { + try { + return convertClassToType(cp.getCPClass(index)); + } catch (InvalidClassFileException e) { + throw convertToError(e); + } + } + + public String getConstantPoolMemberClassType(int index) { + try { + return convertClassToType(cp.getCPRefClass(index)); + } catch (InvalidClassFileException e) { + throw convertToError(e); + } + } + + public String getConstantPoolMemberName(int index) { + try { + return cp.getCPRefName(index); + } catch (InvalidClassFileException e) { + throw convertToError(e); + } + } + + public String getConstantPoolMemberType(int index) { + try { + return cp.getCPRefType(index); + } catch (InvalidClassFileException e) { + throw convertToError(e); + } + } + } +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/shrikeCT/CTUtils.java b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/shrikeCT/CTUtils.java new file mode 100644 index 000000000..6f6e430dc --- /dev/null +++ b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/shrikeCT/CTUtils.java @@ -0,0 +1,34 @@ +/******************************************************************************* + * 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.shrikeBT.shrikeCT; + +import com.ibm.wala.shrikeBT.Constants; +import com.ibm.wala.shrikeBT.analysis.ClassHierarchyStore; +import com.ibm.wala.shrikeCT.ClassReader; +import com.ibm.wala.shrikeCT.InvalidClassFileException; + +/** + * This is a dumping ground for useful functions that manipulate class info. + * + * @author roca@us.ibm.com + */ +public class CTUtils { + public static void addClassToHierarchy(ClassHierarchyStore store, ClassReader cr) throws InvalidClassFileException { + String[] superInterfaces = new String[cr.getInterfaceCount()]; + for (int i = 0; i < superInterfaces.length; i++) { + superInterfaces[i] = CTDecoder.convertClassToType(cr.getInterfaceName(i)); + } + String superName = cr.getSuperName(); + store.setClassInfo(CTDecoder.convertClassToType(cr.getName()), (cr.getAccessFlags() & Constants.ACC_INTERFACE) != 0, (cr + .getAccessFlags() & Constants.ACC_FINAL) != 0, superName != null ? CTDecoder.convertClassToType(superName) : null, + superInterfaces); + } +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/shrikeCT/ClassInstrumenter.java b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/shrikeCT/ClassInstrumenter.java new file mode 100644 index 000000000..e6e56302a --- /dev/null +++ b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/shrikeCT/ClassInstrumenter.java @@ -0,0 +1,523 @@ +/******************************************************************************* + * 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.shrikeBT.shrikeCT; + +import java.util.ArrayList; +import java.util.Arrays; + +import com.ibm.wala.shrikeBT.Compiler; +import com.ibm.wala.shrikeBT.ConstantPoolReader; +import com.ibm.wala.shrikeBT.Constants; +import com.ibm.wala.shrikeBT.ExceptionHandler; +import com.ibm.wala.shrikeBT.Instruction; +import com.ibm.wala.shrikeBT.MethodData; +import com.ibm.wala.shrikeBT.ReturnInstruction; +import com.ibm.wala.shrikeBT.Util; +import com.ibm.wala.shrikeBT.Decoder.InvalidBytecodeException; +import com.ibm.wala.shrikeCT.ClassConstants; +import com.ibm.wala.shrikeCT.ClassReader; +import com.ibm.wala.shrikeCT.ClassWriter; +import com.ibm.wala.shrikeCT.CodeReader; +import com.ibm.wala.shrikeCT.CodeWriter; +import com.ibm.wala.shrikeCT.InvalidClassFileException; +import com.ibm.wala.shrikeCT.LineNumberTableReader; +import com.ibm.wala.shrikeCT.LineNumberTableWriter; +import com.ibm.wala.shrikeCT.LocalVariableTableReader; +import com.ibm.wala.shrikeCT.LocalVariableTableWriter; +import com.ibm.wala.shrikeCT.ClassWriter.Element; + +/** + * This class provides a convenient way to instrument every method in a class. + * It assumes you are using ShrikeCT to read and write classes. It's stateful; + * initially every method is set to the original code read from the class, but + * you can then go in and modify the methods. + */ +final public class ClassInstrumenter { + private boolean[] deletedMethods; + private MethodData[] methods; + private CodeReader[] oldCode; + private ClassReader cr; + private ConstantPoolReader cpr; + private boolean createFakeLineNumbers = false; + private int fakeLineOffset; + + /** + * Create a class instrumenter from raw bytes. + */ + public ClassInstrumenter(byte[] bytes) throws InvalidClassFileException { + this(new ClassReader(bytes)); + } + + /** + * Calling this means that methods without line numbers get fake line numbers + * added: each bytecode instruction is treated as at line 'offset' + the + * offset of the instruction. + */ + public void enableFakeLineNumbers(int offset) { + createFakeLineNumbers = true; + fakeLineOffset = offset; + } + + /** + * Create a class instrumenter from a preinitialized class reader. + */ + public ClassInstrumenter(ClassReader cr) throws InvalidClassFileException { + this.cr = cr; + methods = new MethodData[cr.getMethodCount()]; + oldCode = new CodeReader[methods.length]; + cpr = CTDecoder.makeConstantPoolReader(cr); + deletedMethods = new boolean[methods.length]; + } + + /** + * @return the reader for the class + */ + public ClassReader getReader() { + return cr; + } + + /** + * Implement this interface to instrument every method of a class using + * visitMethods() below. + */ + public static interface MethodExaminer { + /** + * Do something to the method. + */ + public void examineCode(MethodData data); + } + + private void prepareMethod(int i) throws InvalidClassFileException { + if (deletedMethods[i]) { + methods[i] = null; + } else if (methods[i] == null) { + ClassReader.AttrIterator iter = new ClassReader.AttrIterator(); + cr.initMethodAttributeIterator(i, iter); + for (; iter.isValid(); iter.advance()) { + if (iter.getName().equals("Code")) { + CodeReader code = new CodeReader(iter); + CTDecoder d = new CTDecoder(code, cpr); + try { + d.decode(); + } catch (InvalidBytecodeException e) { + throw new InvalidClassFileException(code.getRawOffset(), e.getMessage()); + } + MethodData md = new MethodData(d, cr.getMethodAccessFlags(i), CTDecoder.convertClassToType(cr.getName()), cr + .getMethodName(i), cr.getMethodType(i)); + methods[i] = md; + oldCode[i] = code; + return; + } + } + } + } + + /** + * Indicate that the method should be deleted from the class. + * + * @param i + * the index of the method to delete + */ + public void deleteMethod(int i) { + deletedMethods[i] = true; + } + + private final static ExceptionHandler[] noHandlers = new ExceptionHandler[0]; + + //Xiangyu + //create a empty method body and then user can apply patches later on + public MethodData createEmptyMethodData(String name, String sig, int access) { + //Instruction[] instructions=new Instruction[0]; + Instruction[] instructions = new Instruction[1]; + instructions[0] = ReturnInstruction.make(Constants.TYPE_void); + ExceptionHandler[][] handlers = new ExceptionHandler[instructions.length][]; + Arrays.fill(handlers, noHandlers); + int[] i2b = new int[instructions.length]; + for (int i = 0; i < i2b.length; i++) { + i2b[i] = i; + } + MethodData md = null; + try { + md = new MethodData(access, Util.makeType(cr.getName()), name, sig, instructions, handlers, i2b); + + } catch (InvalidClassFileException ex) { + ex.printStackTrace(); + } + return md; + + } + + /** + * Xiangyu + * + * + */ + public void newMethod(String name, String sig, ArrayList instructions, int access, ClassWriter classWriter, + ClassWriter.Element rawLines) { + Instruction[] ins = (Instruction[]) instructions.toArray(new Instruction[instructions.size()]); + ExceptionHandler[][] handlers = new ExceptionHandler[ins.length][]; + Arrays.fill(handlers, noHandlers); + int[] i2b = new int[ins.length]; + for (int i = 0; i < i2b.length; i++) { + i2b[i] = i; + } + MethodData md = null; + try { + md = new MethodData(access, Util.makeType(cr.getName()), name, sig, ins, handlers, i2b); + } catch (InvalidClassFileException ex) { + ex.printStackTrace(); + } + CTCompiler compiler = new CTCompiler(classWriter, md); + compiler.compile(); + CTCompiler.Output output = compiler.getOutput(); + CodeWriter code = new CodeWriter(classWriter); + code.setMaxStack(output.getMaxStack()); + code.setMaxLocals(output.getMaxLocals()); + code.setCode(output.getCode()); + code.setRawHandlers(output.getRawHandlers()); + + LineNumberTableWriter lines = null; + //I guess it is the line numbers in the java files. + if (rawLines == null) { + // add fake line numbers: just map each bytecode instruction to its own + // 'line' + int[] newLineMap = new int[instructions.size()]; + for (int i = 0; i < newLineMap.length; i++) { + newLineMap[i] = i; + } + int[] rawTable = LineNumberTableWriter.makeRawTable(newLineMap); + lines = new LineNumberTableWriter(classWriter); + lines.setRawTable(rawTable); + } + code.setAttributes(new ClassWriter.Element[] { rawLines == null ? lines : rawLines }); + Element[] elements = { code }; + classWriter.addMethod(access, name, sig, elements); + } + + public void newMethod(MethodData md, ClassWriter classWriter, ClassWriter.Element rawLines) { + CTCompiler compiler = new CTCompiler(classWriter, md); + compiler.compile(); + CTCompiler.Output output = compiler.getOutput(); + CodeWriter code = new CodeWriter(classWriter); + code.setMaxStack(output.getMaxStack()); + code.setMaxLocals(output.getMaxLocals()); + code.setCode(output.getCode()); + code.setRawHandlers(output.getRawHandlers()); + + LineNumberTableWriter lines = null; + //I guess it is the line numbers in the java files. + if (rawLines == null) { + // add fake line numbers: just map each bytecode instruction to its own + // 'line' + + //NOTE:Should not use md.getInstructions().length, because the + //the length of the created code can be smaller than the md's instruction + // length + + //WRONG: int[] newLineMap = new int[md.getInstructions().length]; + int[] newLineMap = new int[code.getCodeLength()]; + for (int i = 0; i < newLineMap.length; i++) { + newLineMap[i] = i; + } + int[] rawTable = LineNumberTableWriter.makeRawTable(newLineMap); + lines = new LineNumberTableWriter(classWriter); + lines.setRawTable(rawTable); + } + code.setAttributes(new ClassWriter.Element[] { rawLines == null ? lines : rawLines }); + Element[] elements = { code }; + //System.out.println("Name:"+md.getName()+" Sig:"+md.getSignature()); + classWriter.addMethod(md.getAccess(), md.getName(), md.getSignature(), elements); + } + + /** + * Do something to every method in the class. This will visit all methods, + * including those already marked for deletion. + * + * @param me + * the visitor to apply to each method + */ + public void visitMethods(MethodExaminer me) throws InvalidClassFileException { + for (int i = 0; i < methods.length; i++) { + prepareMethod(i); + if (methods[i] != null) { + me.examineCode(methods[i]); + } + } + } + + /** + * Get the current state of method i. This can be edited using a MethodEditor. + * + * @param i + * the index of the method to inspect + */ + public MethodData visitMethod(int i) throws InvalidClassFileException { + prepareMethod(i); + return methods[i]; + } + + /** + * Get the original code resource for the method. + * + * @param i + * the index of the method to inspect + */ + public CodeReader getMethodCode(int i) throws InvalidClassFileException { + prepareMethod(i); + return oldCode[i]; + } + + /** + * Reset method i back to the code from the original class, and "undelete" it + * if it was marked for deletion. + * + * @param i + * the index of the method to reset + */ + public void resetMethod(int i) { + deletedMethods[i] = false; + methods[i] = null; + } + + /** + * Replace the code for method i with new code. This also "undeletes" the + * method if it was marked for deletion. + * + * @param i + * the index of the method to replace + */ + public void replaceMethod(int i, MethodData md) { + deletedMethods[i] = false; + methods[i] = md; + oldCode[i] = null; + md.setHasChanged(); + } + + /** + * Check whether any methods in the class have actually been changed. + */ + public boolean isChanged() { + for (int i = 0; i < methods.length; i++) { + if (deletedMethods[i] || (methods[i] != null && methods[i].getHasChanged())) { + return true; + } + } + return false; + } + + /** + * Create a class which is a copy of the original class but with the new + * method code. We return the ClassWriter used, so more methods and fields + * (and other changes) can still be added. + * + * We fix up any debug information to be consistent with the changes to the + * code. + */ + public ClassWriter emitClass() throws InvalidClassFileException { + ClassWriter w = new ClassWriter(); + emitClassInto(w); + return w; + } + + /** + * Copy the contents of the old class, plus any method modifications, into a + * new ClassWriter. The ClassWriter must be empty! + * + * @param w + * the classwriter to copy into. + */ + private void emitClassInto(ClassWriter w) throws InvalidClassFileException { + w.setMajorVersion(cr.getMajorVersion()); + w.setMinorVersion(cr.getMinorVersion()); + w.setRawCP(cr.getCP(), false); + w.setAccessFlags(cr.getAccessFlags()); + w.setNameIndex(cr.getNameIndex()); + w.setSuperNameIndex(cr.getSuperNameIndex()); + w.setInterfaceNameIndices(cr.getInterfaceNameIndices()); + + int fieldCount = cr.getFieldCount(); + for (int i = 0; i < fieldCount; i++) { + w.addRawField(new ClassWriter.RawElement(cr.getBytes(), cr.getFieldRawOffset(i), cr.getFieldRawSize(i))); + } + + for (int i = 0; i < methods.length; i++) { + MethodData md = methods[i]; + if (!deletedMethods[i]) { + if (md == null || !md.getHasChanged()) { + w.addRawMethod(new ClassWriter.RawElement(cr.getBytes(), cr.getMethodRawOffset(i), cr.getMethodRawSize(i))); + } else { + CTCompiler comp = new CTCompiler(w, md); + comp.setPresetConstants(cpr); + + try { + comp.compile(); + } catch (Error ex) { + ex.printStackTrace(); + throw new Error("Error compiling method " + md + ": " + ex.getMessage()); + } catch (Exception ex) { + ex.printStackTrace(); + throw new Error("Error compiling method " + md + ": " + ex.getMessage()); + } + + CodeReader oc = oldCode[i]; + int flags = cr.getMethodAccessFlags(i); + // we're not installing a native method here + flags &= ~ClassConstants.ACC_NATIVE; + w.addMethod(flags, cr.getMethodNameIndex(i), cr.getMethodTypeIndex(i), makeMethodAttributes(i, w, oc, comp.getOutput())); + Compiler.Output[] aux = comp.getAuxiliaryMethods(); + if (aux != null) { + for (int j = 0; j < aux.length; j++) { + Compiler.Output a = aux[j]; + w.addMethod(a.getAccessFlags(), a.getMethodName(), a.getMethodSignature(), makeMethodAttributes(i, w, oc, a)); + } + } + } + } + } + + ClassReader.AttrIterator iter = new ClassReader.AttrIterator(); + cr.initClassAttributeIterator(iter); + for (; iter.isValid(); iter.advance()) { + w.addClassAttribute(new ClassWriter.RawElement(cr.getBytes(), iter.getRawOffset(), iter.getRawSize())); + } + } + + private static CodeWriter makeNewCode(ClassWriter w, Compiler.Output output) { + CodeWriter code = new CodeWriter(w); + code.setMaxStack(output.getMaxStack()); + code.setMaxLocals(output.getMaxLocals()); + code.setCode(output.getCode()); + code.setRawHandlers(output.getRawHandlers()); + return code; + } + + private LineNumberTableWriter makeNewLines(ClassWriter w, CodeReader oldCode, Compiler.Output output) + throws InvalidClassFileException { + int[] newLineMap = null; + int[] oldLineMap = LineNumberTableReader.makeBytecodeToSourceMap(oldCode); + if (oldLineMap != null) { + // Map the old line number map onto the new bytecodes + int[] newToOldMap = output.getNewBytecodesToOldBytecodes(); + newLineMap = new int[newToOldMap.length]; + for (int i = 0; i < newToOldMap.length; i++) { + int old = newToOldMap[i]; + if (old >= 0) { + newLineMap[i] = oldLineMap[old]; + } + } + } else if (createFakeLineNumbers) { + newLineMap = new int[output.getCode().length]; + for (int i = 0; i < newLineMap.length; i++) { + newLineMap[i] = i + fakeLineOffset; + } + } else { + return null; + } + + // Now compress it into the JVM form + int[] rawTable = LineNumberTableWriter.makeRawTable(newLineMap); + if (rawTable == null || rawTable.length == 0) { + return null; + } else { + LineNumberTableWriter lines = new LineNumberTableWriter(w); + lines.setRawTable(rawTable); + return lines; + } + } + + private static LocalVariableTableWriter makeNewLocals(ClassWriter w, CodeReader oldCode, Compiler.Output output) + throws InvalidClassFileException { + int[][] oldMap = LocalVariableTableReader.makeVarMap(oldCode); + if (oldMap != null) { + // Map the old map onto the new bytecodes + int[] newToOldMap = output.getNewBytecodesToOldBytecodes(); + int[][] newMap = new int[newToOldMap.length][]; + int[] lastLocals = null; + for (int i = 0; i < newToOldMap.length; i++) { + int old = newToOldMap[i]; + if (old >= 0) { + newMap[i] = oldMap[old]; + lastLocals = newMap[i]; + } else { + newMap[i] = lastLocals; + } + } + + int[] rawTable = LocalVariableTableWriter.makeRawTable(newMap); + if (rawTable == null || rawTable.length == 0) { + return null; + } else { + LocalVariableTableWriter locals = new LocalVariableTableWriter(w); + locals.setRawTable(rawTable); + return locals; + } + } else { + return null; + } + } + + private ClassWriter.Element[] makeMethodAttributes(int m, ClassWriter w, CodeReader oldCode, Compiler.Output output) + throws InvalidClassFileException { + CodeWriter code = makeNewCode(w, output); + + int codeAttrCount = 0; + LineNumberTableWriter lines = null; + LocalVariableTableWriter locals = null; + if (oldCode != null) { + lines = makeNewLines(w, oldCode, output); + if (lines != null) { + codeAttrCount++; + } + locals = makeNewLocals(w, oldCode, output); + if (locals != null) { + codeAttrCount++; + } + } + ClassWriter.Element[] codeAttributes = new ClassWriter.Element[codeAttrCount]; + int codeAttrIndex = 0; + if (lines != null) { + codeAttributes[0] = lines; + codeAttrIndex++; + } + if (locals != null) { + codeAttributes[codeAttrIndex] = locals; + } + code.setAttributes(codeAttributes); + + ClassReader.AttrIterator iter = new ClassReader.AttrIterator(); + cr.initMethodAttributeIterator(m, iter); + int methodAttrCount = iter.getRemainingAttributesCount(); + if (oldCode == null) { + methodAttrCount++; + } + ClassWriter.Element[] methodAttributes = new ClassWriter.Element[methodAttrCount]; + for (int i = 0; iter.isValid(); iter.advance()) { + if (iter.getName().equals("Code")) { + methodAttributes[i] = code; + code = null; + if (oldCode == null) { + throw new Error("No old code provided, but Code attribute found"); + } + } else { + methodAttributes[i] = new ClassWriter.RawElement(cr.getBytes(), iter.getRawOffset(), iter.getRawSize()); + } + i++; + } + if (oldCode == null) { + if (code == null) { + throw new Error("Old code not provided but existing code was found and replaced"); + } + methodAttributes[methodAttrCount - 1] = code; + } + + return methodAttributes; + } +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/shrikeCT/OfflineInstrumenter.java b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/shrikeCT/OfflineInstrumenter.java new file mode 100644 index 000000000..7e00eec42 --- /dev/null +++ b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/shrikeCT/OfflineInstrumenter.java @@ -0,0 +1,90 @@ +/******************************************************************************* + * 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.shrikeBT.shrikeCT; + +import java.io.BufferedInputStream; +import java.io.IOException; +import java.io.OutputStream; + +import com.ibm.wala.shrikeBT.Util; +import com.ibm.wala.shrikeBT.tools.OfflineInstrumenterBase; +import com.ibm.wala.shrikeCT.ClassWriter; +import com.ibm.wala.shrikeCT.InvalidClassFileException; + +/** + * This class provides a convenient way to iterate through a collection of Java + * classes and instrument their code. This is just a specialization of + * OfflineInstrumenterBase to use the shrikeCT functionality. + */ +final public class OfflineInstrumenter extends OfflineInstrumenterBase { + /** + * Create an empty collection of classes to instrument. + */ + public OfflineInstrumenter() { + } + + protected Object makeClassFromStream(BufferedInputStream s) throws IOException { + byte[] bytes = new byte[s.available()]; + Util.readFully(s, bytes); + try { + return new ClassInstrumenter(bytes); + } catch (InvalidClassFileException e) { + throw new IOException("Class is invalid: " + e.getMessage()); + } + } + + protected String getClassName(Object cl) { + try { + return ((ClassInstrumenter) cl).getReader().getName().replace('/', '.'); + } catch (InvalidClassFileException e) { + return null; + } + } + + protected void writeClassTo(Object cl, Object mods, OutputStream s) throws IOException { + ClassInstrumenter ci = (ClassInstrumenter) cl; + ClassWriter cw = (ClassWriter) mods; + if (cw == null) { + s.write(ci.getReader().getBytes()); + } else { + s.write(cw.makeBytes()); + } + } + + /** + * Get the next class to be instrumented. + */ + public ClassInstrumenter nextClass() throws IOException { + return (ClassInstrumenter) internalNextClass(); + } + + /** + * Update the original class with some method changes. 'code' should be the + * result of out.emitClass(). You can add new fields and methods to 'code' (or + * make other changes) before calling this method. + */ + public void outputModifiedClass(ClassInstrumenter out, ClassWriter code) throws IOException { + internalOutputModifiedClass(out, code); + } + + /** + * Update the original class with some method changes. This method calls + * out.emitClass() for you. + */ + public void outputModifiedClass(ClassInstrumenter out) throws IOException { + try { + internalOutputModifiedClass(out, out.emitClass()); + } catch (InvalidClassFileException e) { + e.printStackTrace(); + throw new IOException("Invalid class file"); + } + } +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/shrikeCT/tools/AddSerialVersion.java b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/shrikeCT/tools/AddSerialVersion.java new file mode 100644 index 000000000..dc1c815f7 --- /dev/null +++ b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/shrikeCT/tools/AddSerialVersion.java @@ -0,0 +1,187 @@ +/******************************************************************************* + * 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.shrikeBT.shrikeCT.tools; + +import java.io.DataOutputStream; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.OutputStream; +import java.security.DigestOutputStream; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.util.Arrays; +import java.util.Comparator; + +import com.ibm.wala.shrikeBT.Util; +import com.ibm.wala.shrikeCT.ClassReader; +import com.ibm.wala.shrikeCT.ClassWriter; +import com.ibm.wala.shrikeCT.ConstantValueWriter; +import com.ibm.wala.shrikeCT.InvalidClassFileException; + +public class AddSerialVersion { + /** + * This method computes the serialVersionUID for class r (if there isn't one + * already) and adds the field to the classwriter w. + * + * When run as a program, just takes a list of class files as command line + * arguments and computes their serialVersionUIDs. + */ + public static void addSerialVersionUID(ClassReader r, ClassWriter w) throws InvalidClassFileException { + int numFields = r.getFieldCount(); + for (int i = 0; i < numFields; i++) { + if (r.getFieldName(i).equals("serialVersionUID")) { + return; // already has a serialVersionUID + } + } + + long UID = computeSerialVersionUID(r); + w.addField(ClassReader.ACC_PUBLIC | ClassReader.ACC_STATIC | ClassReader.ACC_FINAL, "serialVersionUID", "J", + new ClassWriter.Element[] { new ConstantValueWriter(w, UID) }); + } + + /** + * This class implements a stream that just discards everything written to it. + */ + public static final class SinkOutputStream extends OutputStream { + public void write(int b) { + } + + public void write(byte[] b) { + } + + public void write(byte[] b, int off, int len) { + } + } + + /** + * This method computes the serialVersionUID for class r. See the + * specification at + * http://java.sun.com/j2se/1.4.2/docs/guide/serialization/spec/class.html + */ + public static long computeSerialVersionUID(final ClassReader r) throws InvalidClassFileException { + MessageDigest digest; + try { + digest = MessageDigest.getInstance("SHA"); + } catch (NoSuchAlgorithmException e) { + throw new Error("SHA algorithm not supported: " + e.getMessage()); + } + SinkOutputStream sink = new SinkOutputStream(); + DataOutputStream out = new DataOutputStream(new DigestOutputStream(sink, digest)); + + try { + // step 1 + out.writeUTF(r.getName()); + // step 2 + out.writeInt(r.getAccessFlags()); + + // step 3 + String[] interfaces = r.getInterfaceNames(); + Arrays.sort(interfaces); + for (int i = 0; i < interfaces.length; i++) { + out.writeUTF(interfaces[i]); + } + + // step 4 + Integer[] fields = new Integer[r.getFieldCount()]; + final String[] fieldNames = new String[fields.length]; + int fieldCount = 0; + for (int f = 0; f < fields.length; f++) { + int flags = r.getFieldAccessFlags(f); + if ((flags & ClassReader.ACC_PRIVATE) == 0 || (flags & (ClassReader.ACC_STATIC | ClassReader.ACC_TRANSIENT)) == 0) { + fields[fieldCount] = new Integer(f); + fieldNames[f] = r.getFieldName(f); + fieldCount++; + } + } + Arrays.sort(fields, 0, fieldCount, new Comparator() { + public int compare(Integer o1, Integer o2) { + String name1 = fieldNames[((Integer) o1).intValue()]; + String name2 = fieldNames[((Integer) o2).intValue()]; + return name1.compareTo(name2); + } + }); + for (int i = 0; i < fieldCount; i++) { + int f = ((Integer) fields[i]).intValue(); + out.writeUTF(fieldNames[f]); + out.writeInt(r.getFieldAccessFlags(f)); + out.writeUTF(r.getFieldType(f)); + } + + // steps 5, 6 and 7 + Integer[] methods = new Integer[r.getMethodCount()]; + final int[] methodKinds = new int[methods.length]; + final String[] methodSigs = new String[methods.length]; + int methodCount = 0; + for (int m = 0; m < methodSigs.length; m++) { + String name = r.getMethodName(m); + int flags = r.getMethodAccessFlags(m); + if (name.equals("") || (flags & ClassReader.ACC_PRIVATE) == 0) { + methods[methodCount] = new Integer(m); + methodSigs[m] = name + r.getMethodType(m); + if (name.equals("")) { + methodKinds[m] = 0; + } else if (name.equals("")) { + methodKinds[m] = 1; + } else { + methodKinds[m] = 2; + } + methodCount++; + } + } + Arrays.sort(methods, 0, methodCount, new Comparator() { + public int compare(Integer o1, Integer o2) { + int m1 = ((Integer) o1).intValue(); + int m2 = ((Integer) o2).intValue(); + if (methodKinds[m1] != methodKinds[m2]) { + return methodKinds[m1] - methodKinds[m2]; + } + String name1 = methodSigs[m1]; + String name2 = methodSigs[m2]; + return name1.compareTo(name2); + } + }); + for (int i = 0; i < methodCount; i++) { + int m = ((Integer) methods[i]).intValue(); + out.writeUTF(r.getMethodName(m)); + out.writeInt(r.getMethodAccessFlags(m)); + out.writeUTF(r.getMethodType(m)); + } + } catch (IOException e1) { + throw new Error("Unexpected IOException: " + e1.getMessage()); + } finally { + try { + out.close(); + } catch (IOException e2) { + } + } + + byte[] hash = digest.digest(); + return (hash[0] & 0xFF) | (hash[1] & 0xFF) << 8 | (hash[2] & 0xFF) << 16 | hash[3] << 24 | (hash[4] & 0xFF) << 32 + | (hash[5] & 0xFF) << 40 | (hash[6] & 0xFF) << 48 | (hash[7] & 0xFF) << 56; + } + + public static void main(String[] args) { + for (int i = 0; i < args.length; i++) { + try { + byte[] data = Util.readFully(new FileInputStream(args[i])); + ClassReader r = new ClassReader(data); + System.out.println(Util.makeClass(r.getName()) + ": serialVersionUID = " + computeSerialVersionUID(r)); + } catch (FileNotFoundException e) { + System.err.println("File not found: " + args[i]); + } catch (IOException e) { + System.err.println("Error reading file: " + args[i]); + } catch (InvalidClassFileException e) { + System.err.println("Invalid class file: " + args[i]); + } + } + } +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/shrikeCT/tools/BatchVerifier.java b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/shrikeCT/tools/BatchVerifier.java new file mode 100644 index 000000000..8b36101b4 --- /dev/null +++ b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/shrikeCT/tools/BatchVerifier.java @@ -0,0 +1,128 @@ +/******************************************************************************* + * 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.shrikeBT.shrikeCT.tools; + +import java.io.BufferedWriter; +import java.io.FileWriter; +import java.io.PrintWriter; + +import com.ibm.wala.shrikeBT.Decoder; +import com.ibm.wala.shrikeBT.Disassembler; +import com.ibm.wala.shrikeBT.MethodData; +import com.ibm.wala.shrikeBT.analysis.ClassHierarchyStore; +import com.ibm.wala.shrikeBT.analysis.Verifier; +import com.ibm.wala.shrikeBT.analysis.Analyzer.FailureException; +import com.ibm.wala.shrikeBT.shrikeCT.CTDecoder; +import com.ibm.wala.shrikeBT.shrikeCT.CTUtils; +import com.ibm.wala.shrikeBT.shrikeCT.ClassInstrumenter; +import com.ibm.wala.shrikeBT.shrikeCT.OfflineInstrumenter; +import com.ibm.wala.shrikeCT.ClassReader; +import com.ibm.wala.shrikeCT.CodeReader; +import com.ibm.wala.shrikeCT.InvalidClassFileException; + +/** + * This is a demo class. + * + * Class files are taken as input arguments (or if there are none, from standard + * input). The methods in those files are instrumented: we insert a + * System.err.println() at ever method call, and a System.err.println() at every + * method entry. + * + * In Unix, I run it like this: java -cp ~/dev/shrike/shrike + * com.ibm.wala.shrikeBT.shrikeCT.tools.BatchVerifier test.jar -o output.jar + * + * The instrumented classes are placed in the directory "output" under the + * current directory. Disassembled code is written to the file "report" under + * the current directory. + */ +public class BatchVerifier { + private static boolean disasm = false; + private static ClassHierarchyStore store = new ClassHierarchyStore(); + private static int errors = 0; + + public static void main(String[] args) throws Exception { + OfflineInstrumenter oi = new OfflineInstrumenter(); + args = oi.parseStandardArgs(args); + + for (int i = 0; i < args.length; i++) { + if (args[i].equals("-d")) { + disasm = true; + } + } + + PrintWriter w = new PrintWriter(new BufferedWriter(new FileWriter("report", false))); + + oi.beginTraversal(); + ClassInstrumenter ci; + while ((ci = oi.nextClass()) != null) { + ClassReader cr = ci.getReader(); + CTUtils.addClassToHierarchy(store, cr); + } + + oi.beginTraversal(); + while ((ci = oi.nextClass()) != null) { + doClass(ci.getReader(), w); + } + + oi.close(); + + if (errors > 0) { + System.err.println(errors + " error" + (errors > 1 ? "s" : "") + " detected"); + } + } + + private static void doClass(final ClassReader cr, PrintWriter w) throws Exception { + int methodCount = cr.getMethodCount(); + w.write("Verifying " + cr.getName() + "\n"); + w.flush(); + + ClassReader.AttrIterator iter = new ClassReader.AttrIterator(); + + for (int i = 0; i < methodCount; i++) { + cr.initMethodAttributeIterator(i, iter); + for (; iter.isValid(); iter.advance()) { + if (iter.getName().equals("Code")) { + w.write("Verifying " + cr.getName() + "." + cr.getMethodName(i) + " " + cr.getMethodType(i) + ":\n"); + w.flush(); + + CodeReader code = new CodeReader(iter); + CTDecoder d = new CTDecoder(code); + try { + d.decode(); + } catch (Decoder.InvalidBytecodeException e) { + throw new InvalidClassFileException(code.getRawOffset(), e.getMessage()); + } + MethodData md = new MethodData(d, cr.getMethodAccessFlags(i), CTDecoder.convertClassToType(cr.getName()), cr + .getMethodName(i), cr.getMethodType(i)); + + if (disasm) { + w.write("ShrikeBT code:\n"); + (new Disassembler(md)).disassembleTo(w); + w.flush(); + } + + Verifier v = new Verifier(md); + try { + v.verify(); + } catch (FailureException e) { + w.println("ERROR: VERIFICATION FAILED"); + e.printStackTrace(w); + e.printPath(w); + errors++; + w.flush(); + } + + break; + } + } + } + } +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/shrikeCT/tools/ClassPrinter.java b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/shrikeCT/tools/ClassPrinter.java new file mode 100644 index 000000000..b145d9976 --- /dev/null +++ b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/shrikeCT/tools/ClassPrinter.java @@ -0,0 +1,382 @@ +/******************************************************************************* + * 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.shrikeBT.shrikeCT.tools; + +import java.io.BufferedWriter; +import java.io.IOException; +import java.io.OutputStreamWriter; +import java.io.PrintWriter; +import java.lang.reflect.Field; + +import com.ibm.wala.shrikeBT.Constants; +import com.ibm.wala.shrikeBT.Disassembler; +import com.ibm.wala.shrikeBT.Decoder.InvalidBytecodeException; +import com.ibm.wala.shrikeBT.shrikeCT.CTDecoder; +import com.ibm.wala.shrikeBT.shrikeCT.ClassInstrumenter; +import com.ibm.wala.shrikeBT.shrikeCT.OfflineInstrumenter; +import com.ibm.wala.shrikeCT.ClassConstants; +import com.ibm.wala.shrikeCT.ClassReader; +import com.ibm.wala.shrikeCT.CodeReader; +import com.ibm.wala.shrikeCT.ConstantPoolParser; +import com.ibm.wala.shrikeCT.ConstantValueReader; +import com.ibm.wala.shrikeCT.InvalidClassFileException; +import com.ibm.wala.shrikeCT.LineNumberTableReader; +import com.ibm.wala.shrikeCT.LocalVariableTableReader; +import com.ibm.wala.shrikeCT.SourceFileReader; + +/** + * This class prints the contents of a class file. It's like an alternative to + * javap that shows more information. + * + * In Unix I run it like this: java -cp ~/dev/shrike/shrike + * com.ibm.wala.shrikeBT.shrikeCT.tools.ClassPrinter test.jar This will print the + * contents of every class in the JAR file. + */ +public class ClassPrinter { + private PrintWriter w; + private boolean printLineNumberInfo = true; + private boolean printConstantPool = true; + + /** + * Get ready to print a class to the given output stream. + */ + public ClassPrinter(PrintWriter w) { + this.w = w; + } + + /** + * Controls whether to print line number information. The default is 'true'. + */ + public void setPrintLineNumberInfo(boolean b) { + printLineNumberInfo = b; + } + + /** + * Controls whether to print all the constant pool entries. The default is + * 'true'. + */ + public void setPrintConstantPool(boolean b) { + printConstantPool = b; + } + + public static void main(String[] args) throws Exception { + OfflineInstrumenter oi = new OfflineInstrumenter(); + args = oi.parseStandardArgs(args); + + PrintWriter w = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out))); + + ClassPrinter p = new ClassPrinter(w); + + ClassInstrumenter ci; + oi.beginTraversal(); + while ((ci = oi.nextClass()) != null) { + try { + p.doClass(ci.getReader()); + } finally { + w.flush(); + } + } + + oi.close(); + } + + private static final char[] hexChars = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; + + private static String makeHex(byte[] bytes, int pos, int len, int padTo) { + StringBuffer b = new StringBuffer(); + for (int i = pos; i < pos + len; i++) { + byte v = bytes[i]; + b.append(hexChars[(v >> 4) & 0xF]); + b.append(hexChars[v & 0xF]); + } + while (b.length() < padTo) { + b.append(' '); + } + return b.toString(); + } + + private static String makeChars(byte[] bytes, int pos, int len) { + StringBuffer b = new StringBuffer(); + for (int i = pos; i < pos + len; i++) { + char ch = (char) bytes[i]; + if (ch < 32 || ch > 127) { + b.append('.'); + } else { + b.append(ch); + } + } + return b.toString(); + } + + private static String getClassName(ClassReader cr, int index) throws InvalidClassFileException { + if (index == 0) { + return "any"; + } else { + return cr.getCP().getCPClass(index); + } + } + + private static String dumpFlags(int flags) { + StringBuffer buf = new StringBuffer(); + Class c = Constants.class; + Field[] fs = c.getDeclaredFields(); + for (int i = 0; i < fs.length; i++) { + String name = fs[i].getName(); + if (name.startsWith("ACC_")) { + int val; + try { + val = fs[i].getInt(null); + } catch (IllegalArgumentException e) { + throw new Error(e.getMessage()); + } catch (IllegalAccessException e) { + throw new Error(e.getMessage()); + } + if ((flags & val) != 0) { + if (buf.length() > 0) { + buf.append(" "); + } + buf.append(name.substring(4).toLowerCase()); + } + } + } + return "0x" + Integer.toString(16, flags) + "(" + buf.toString() + ")"; + } + + private void dumpAttributes(ClassReader cr, int i, ClassReader.AttrIterator attrs) throws InvalidClassFileException, + InvalidBytecodeException, IOException { + for (; attrs.isValid(); attrs.advance()) { + String name = attrs.getName(); + w.write(" " + name + ": @" + Integer.toString(attrs.getRawOffset(), 16) + "\n"); + if (name.equals("Code")) { + CodeReader code = new CodeReader(attrs); + + w.write(" maxstack: " + code.getMaxStack() + "\n"); + w.write(" maxlocals: " + code.getMaxLocals() + "\n"); + + w.write(" bytecode:\n"); + int[] rawHandlers = code.getRawHandlers(); + CTDecoder decoder = new CTDecoder(code); + decoder.decode(); + Disassembler disasm = new Disassembler(decoder.getInstructions(), decoder.getHandlers(), decoder + .getInstructionsToBytecodes()); + disasm.disassembleTo(" ", w); + + w.write(" exception handlers:\n"); + for (int e = 0; e < rawHandlers.length; e += 4) { + w.write(" " + rawHandlers[e] + " to " + rawHandlers[e + 1] + " catch " + getClassName(cr, rawHandlers[e + 3]) + + " at " + rawHandlers[e + 2] + "\n"); + } + + ClassReader.AttrIterator codeAttrs = new ClassReader.AttrIterator(); + code.initAttributeIterator(codeAttrs); + for (; codeAttrs.isValid(); codeAttrs.advance()) { + String cName = codeAttrs.getName(); + w.write(" " + cName + ": " + Integer.toString(codeAttrs.getRawOffset(), 16) + "\n"); + } + + if (printLineNumberInfo) { + int[] map = LineNumberTableReader.makeBytecodeToSourceMap(code); + if (map != null) { + w.write(" line number map:\n"); + String line = null; + int count = 0; + for (int j = 0; j < map.length; j++) { + String line2 = " " + j + ": " + map[j]; + if (line == null || line2 == null || !line2.substring(line2.indexOf(':')).equals(line.substring(line.indexOf(':')))) { + if (count > 1) { + w.write(" (" + count + " times)\n"); + } else if (count > 0) { + w.write("\n"); + } + count = 0; + line = line2; + w.write(line); + } + count++; + } + if (count > 1) { + w.write(" (" + count + " times)\n"); + } else if (count > 0) { + w.write("\n"); + } + } + } + + int[][] locals = LocalVariableTableReader.makeVarMap(code); + if (locals != null) { + w.write(" local variable map:\n"); + String line = null; + int count = 0; + for (int j = 0; j < locals.length; j++) { + int[] vars = locals[j]; + String line2 = null; + if (vars != null) { + StringBuffer buf = new StringBuffer(); + buf.append(" " + j + ":"); + for (int k = 0; k < vars.length; k += 2) { + if (vars[k] != 0) { + String n = cr.getCP().getCPUtf8(vars[k]) + "(" + cr.getCP().getCPUtf8(vars[k + 1]) + ")"; + buf.append(" " + (k / 2) + ":" + n); + } + } + line2 = buf.toString(); + } + if (line == null || line2 == null || !line2.substring(line2.indexOf(':')).equals(line.substring(line.indexOf(':')))) { + if (count > 1) { + w.write(" (" + count + " times)\n"); + } else if (count > 0) { + w.write("\n"); + } + count = 0; + line = line2; + if (line != null) { + w.write(line); + } + } + if (line != null) { + count++; + } + } + if (count > 1) { + w.write(" (" + count + " times)\n"); + } else if (count > 0) { + w.write("\n"); + } + } + } else if (name.equals("ConstantValue")) { + ConstantValueReader cv = new ConstantValueReader(attrs); + w.write(" value: " + getCPItemString(cr.getCP(), cv.getValueCPIndex()) + "\n"); + } else if (name.equals("SourceFile")) { + SourceFileReader sr = new SourceFileReader(attrs); + w.write(" file: " + cr.getCP().getCPUtf8(sr.getSourceFileCPIndex()) + "\n"); + } else { + int len = attrs.getDataSize(); + int pos = attrs.getDataOffset(); + while (len > 0) { + int amount = Math.min(16, len); + w.write(" " + makeHex(cr.getBytes(), pos, amount, 32) + " " + makeChars(cr.getBytes(), pos, amount) + "\n"); + len -= amount; + pos += amount; + } + } + } + } + + private static String getCPItemString(ConstantPoolParser cp, int i) throws InvalidClassFileException { + int t = cp.getItemType(i); + switch (t) { + case ClassConstants.CONSTANT_Utf8: + return "Utf8 " + quoteString(cp.getCPUtf8(i)); + case ClassConstants.CONSTANT_Class: + return "Class " + cp.getCPClass(i); + case ClassConstants.CONSTANT_String: + return "String " + quoteString(cp.getCPString(i)); + case ClassConstants.CONSTANT_Integer: + return "Integer " + cp.getCPInt(i); + case ClassConstants.CONSTANT_Float: + return "Float " + cp.getCPFloat(i); + case ClassConstants.CONSTANT_Double: + return "Double " + cp.getCPDouble(i); + case ClassConstants.CONSTANT_Long: + return "Long " + cp.getCPLong(i); + case ClassConstants.CONSTANT_MethodRef: + return "Method " + cp.getCPRefClass(i) + " " + cp.getCPRefName(i) + " " + cp.getCPRefType(i); + case ClassConstants.CONSTANT_FieldRef: + return "Field " + cp.getCPRefClass(i) + " " + cp.getCPRefName(i) + " " + cp.getCPRefType(i); + case ClassConstants.CONSTANT_InterfaceMethodRef: + return "InterfaceMethod " + cp.getCPRefClass(i) + " " + cp.getCPRefName(i) + " " + cp.getCPRefType(i); + case ClassConstants.CONSTANT_NameAndType: + return "NameAndType " + cp.getCPNATType(i) + " " + cp.getCPNATName(i); + default: + return "Unknown type " + t; + } + } + + private static String quoteString(String string) { + StringBuffer buf = new StringBuffer(); + buf.append('"'); + for (int i = 0; i < string.length(); i++) { + char ch = string.charAt(i); + switch (ch) { + case '\r': + buf.append("\\r"); + break; + case '\n': + buf.append("\\n"); + break; + case '\\': + buf.append("\\\\"); + break; + case '\t': + buf.append("\\t"); + break; + case '\"': + buf.append("\\\""); + break; + default: + if (ch >= 32 && ch <= 127) { + buf.append(ch); + } else { + buf.append("\\u"); + String h = makeHex(new byte[] { (byte) (ch >> 8), (byte) ch }, 0, 2, 0); + for (int j = 4 - h.length(); j > 0; j--) { + buf.append('0'); + } + buf.append(h); + } + } + } + buf.append('"'); + return buf.toString(); + } + + /** + * Print a class. + */ + public void doClass(final ClassReader cr) throws InvalidClassFileException, InvalidBytecodeException, IOException { + w.write("Class: " + cr.getName() + "\n"); + + if (printConstantPool) { + ConstantPoolParser cp = cr.getCP(); + for (int i = 1; i < cp.getItemCount(); i++) { + int t = cp.getItemType(i); + if (t > 0) { + w.write(" Constant pool item " + i + ": "); + w.write(getCPItemString(cp, i)); + w.write("\n"); + } + } + } + + ClassReader.AttrIterator attrs = new ClassReader.AttrIterator(); + cr.initClassAttributeIterator(attrs); + dumpAttributes(cr, 0, attrs); + w.write("\n"); + + int fieldCount = cr.getFieldCount(); + w.write(fieldCount + " fields:\n"); + for (int i = 0; i < fieldCount; i++) { + w.write(cr.getFieldName(i) + " " + cr.getFieldType(i) + " " + dumpFlags(cr.getFieldAccessFlags(i)) + "\n"); + cr.initFieldAttributeIterator(i, attrs); + dumpAttributes(cr, i, attrs); + } + w.write("\n"); + + int methodCount = cr.getMethodCount(); + w.write(methodCount + " methods:\n"); + for (int i = 0; i < methodCount; i++) { + w.write(cr.getMethodName(i) + " " + cr.getMethodType(i) + " " + dumpFlags(cr.getMethodAccessFlags(i)) + "\n"); + cr.initMethodAttributeIterator(i, attrs); + dumpAttributes(cr, i, attrs); + } + w.write("\n"); + } +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/shrikeCT/tools/ClassSearcher.java b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/shrikeCT/tools/ClassSearcher.java new file mode 100644 index 000000000..cef2c9d48 --- /dev/null +++ b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/shrikeCT/tools/ClassSearcher.java @@ -0,0 +1,70 @@ +/******************************************************************************* + * 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.shrikeBT.shrikeCT.tools; + +import java.io.BufferedWriter; +import java.io.FileWriter; +import java.io.Writer; + +import com.ibm.wala.shrikeBT.shrikeCT.ClassInstrumenter; +import com.ibm.wala.shrikeBT.shrikeCT.OfflineInstrumenter; +import com.ibm.wala.shrikeCT.ClassReader; +import com.ibm.wala.shrikeCT.ConstantPoolParser; + +/** + * This is a demo class. + * + * Class files are taken as input arguments (or if there are none, from standard + * input). We search those class files for all references to the Java library + * classes "SoftReference" or "WeakReference". This is just a demo to show how + * to write a simple tool like this. Here we're using the OfflineInstrumenter + * class to manage loading a set of class files and JARs for analysis; we don't + * actually modify any code. + * + * In Unix, I run it like this: java -cp ~/dev/shrike/shrike + * com.ibm.wala.shrikeBT.shrikeCT.tools.ClassSearcher test.jar -o output.jar + */ +public class ClassSearcher { + private static OfflineInstrumenter instrumenter; + + private static int scanned = 0; + + public static void main(String[] args) throws Exception { + instrumenter = new OfflineInstrumenter(); + + Writer w = new BufferedWriter(new FileWriter("report", true)); + + instrumenter.parseStandardArgs(args); + instrumenter.beginTraversal(); + ClassInstrumenter ci; + while ((ci = instrumenter.nextClass()) != null) { + doClass(ci, w, instrumenter.getLastClassResourceName()); + } + instrumenter.close(); + w.close(); + + System.out.println("Classes scanned: " + scanned); + } + + private static void doClass(final ClassInstrumenter ci, Writer w, String resource) throws Exception { + scanned++; + + String cl1 = "java/lang/ref/WeakReference"; + String cl2 = "java/lang/ref/SoftReference"; + ClassReader r = ci.getReader(); + ConstantPoolParser cp = r.getCP(); + for (int i = 1; i < cp.getItemCount(); i++) { + if (cp.getItemType(i) == ConstantPoolParser.CONSTANT_Class && (cp.getCPClass(i).equals(cl1) || cp.getCPClass(i).equals(cl2))) { + w.write(cp.getCPClass(i) + " " + resource + " " + r.getName() + "\n"); + } + } + } +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/shrikeCT/tools/MethodTracer.java b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/shrikeCT/tools/MethodTracer.java new file mode 100644 index 000000000..33e6d5055 --- /dev/null +++ b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/shrikeCT/tools/MethodTracer.java @@ -0,0 +1,150 @@ +/******************************************************************************* + * 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.shrikeBT.shrikeCT.tools; + +import java.io.BufferedWriter; +import java.io.FileWriter; +import java.io.PrintStream; +import java.io.Writer; + +import com.ibm.wala.shrikeBT.ConstantInstruction; +import com.ibm.wala.shrikeBT.Disassembler; +import com.ibm.wala.shrikeBT.Instruction; +import com.ibm.wala.shrikeBT.InvokeInstruction; +import com.ibm.wala.shrikeBT.MethodData; +import com.ibm.wala.shrikeBT.MethodEditor; +import com.ibm.wala.shrikeBT.Util; +import com.ibm.wala.shrikeBT.analysis.Verifier; +import com.ibm.wala.shrikeBT.shrikeCT.ClassInstrumenter; +import com.ibm.wala.shrikeBT.shrikeCT.OfflineInstrumenter; + +/** + * This is a demo class. + * + * Class files are taken as input arguments (or if there are none, from standard + * input). The methods in those files are instrumented: we insert a + * System.err.println() at ever method call, and a System.err.println() at every + * method entry. + * + * In Unix, I run it like this: java -cp ~/dev/shrike/shrike + * com.ibm.wala.shrikeBT.shrikeCT.tools.MethodTracer test.jar -o output.jar + * + * All modified classes are copied into "output.jar". Some classes may not be + * modified. To run the resulting code, you should put output.jar and test.jar + * on the classpath, and put output.jar before test.jar. Disassembled code is + * written to the file "report" under the current directory. + */ +public class MethodTracer { + private final static boolean disasm = true; + private final static boolean verify = true; + private final static boolean INSTRUMENT_CALLERS = false; + + private static OfflineInstrumenter instrumenter; + + public static void main(String[] args) throws Exception { + for (int i = 0; i < 1; i++) { + instrumenter = new OfflineInstrumenter(); + + Writer w = new BufferedWriter(new FileWriter("report", false)); + + instrumenter.parseStandardArgs(args); + instrumenter.setPassUnmodifiedClasses(false); + instrumenter.beginTraversal(); + ClassInstrumenter ci; + while ((ci = instrumenter.nextClass()) != null) { + doClass(ci, w); + } + instrumenter.close(); + } + } + + // Keep these commonly used instructions around. This trick can speed up + // instrumentation tools a bit. It's always safe because Instruction objects + // are always immutable and shareable. + static final Instruction getSysErr = Util.makeGet(System.class, "err"); + static final Instruction callPrintln = Util.makeInvoke(PrintStream.class, "println", new Class[] { String.class }); + + private static void doClass(final ClassInstrumenter ci, Writer w) throws Exception { + w.write("Class: " + ci.getReader().getName() + "\n"); + w.flush(); + + for (int i = 0; i < ci.getReader().getMethodCount(); i++) { + MethodData d = ci.visitMethod(i); + + // d could be null, e.g., if the method is abstract or native + if (d != null) { + w.write("Instrumenting " + ci.getReader().getMethodName(i) + " " + ci.getReader().getMethodType(i) + ":\n"); + w.flush(); + + if (disasm) { + w.write("Initial ShrikeBT code:\n"); + (new Disassembler(d)).disassembleTo(w); + w.flush(); + } + + if (verify) { + // verify the incoming code + Verifier v = new Verifier(d); + v.verify(); + } + + MethodEditor me = new MethodEditor(d); + me.beginPass(); + final String msg0 = "Call to " + Util.makeClass("L" + ci.getReader().getName() + ";") + "." + + ci.getReader().getMethodName(i); + + me.insertAtStart(new MethodEditor.Patch() { + public void emitTo(MethodEditor.Output w) { + w.emit(getSysErr); + w.emit(ConstantInstruction.makeString(msg0)); + w.emit(callPrintln); + } + }); + if (INSTRUMENT_CALLERS) { + Instruction[] ins = d.getInstructions(); + for (int k = 0; k < ins.length; k++) { + if (ins[k] instanceof InvokeInstruction) { + InvokeInstruction instr = (InvokeInstruction) ins[k]; + final String msg = "Call from " + Util.makeClass("L" + ci.getReader().getName() + ";") + "." + + ci.getReader().getMethodName(i) + ":" + k + " to target " + Util.makeClass(instr.getClassType()) + "." + + instr.getMethodName(); + me.insertBefore(k, new MethodEditor.Patch() { + public void emitTo(MethodEditor.Output w) { + w.emit(getSysErr); + w.emit(ConstantInstruction.makeString(msg)); + w.emit(callPrintln); + } + }); + } + } + } + // this updates the data d + me.applyPatches(); + + if (disasm) { + w.write("Final ShrikeBT code:\n"); + (new Disassembler(d)).disassembleTo(w); + w.flush(); + } + + if (verify) { + // verify outgoing code + Verifier v = new Verifier(d); + v.verify(); + } + } + } + + if (ci.isChanged()) { + instrumenter.outputModifiedClass(ci); + } + } +} diff --git a/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/tools/MethodOptimizer.java b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/tools/MethodOptimizer.java new file mode 100644 index 000000000..3c47bcd56 --- /dev/null +++ b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/tools/MethodOptimizer.java @@ -0,0 +1,463 @@ +/******************************************************************************* + * 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.shrikeBT.tools; + +import java.util.Arrays; +import java.util.BitSet; + +import com.ibm.wala.shrikeBT.DupInstruction; +import com.ibm.wala.shrikeBT.ExceptionHandler; +import com.ibm.wala.shrikeBT.Instruction; +import com.ibm.wala.shrikeBT.LoadInstruction; +import com.ibm.wala.shrikeBT.MethodData; +import com.ibm.wala.shrikeBT.MethodEditor; +import com.ibm.wala.shrikeBT.PopInstruction; +import com.ibm.wala.shrikeBT.StoreInstruction; +import com.ibm.wala.shrikeBT.Util; +import com.ibm.wala.shrikeBT.MethodEditor.Output; +import com.ibm.wala.shrikeBT.info.LocalAllocator; + +public final class MethodOptimizer { + private MethodData data; + private Instruction[] instructions; + private ExceptionHandler[][] handlers; + private MethodEditor editor; + // The value at index [i][N] is the index of the only instruction which pushes + // a value onto + // the stack which is #N popped by instruction i, or -2 if there is no such + // instruction + // or -1 if there is more than one such instruction. + private int[][] uniqueStackDefLocations; + // The value at index i[N] is the index of the only instruction which pops a + // value off + // the stack which is pushed by instruction i, or -2 if there is no such + // instruction + // or -1 if there is more than one such instruction. + private int[] uniqueStackUseLocations; + private int[] stackSizes; + private int[][] backEdges; + // The value at index i is the index of the only instruction which stores a + // value onto + // the stack which is popped by instruction i, or -2 if there is no such + // instruction + // or -1 if there is more than one such instruction. + + final static int[] noEdges = new int[0]; + + public MethodOptimizer(MethodData d, MethodEditor e) { + this.data = d; + this.editor = e; + } + + public MethodOptimizer(MethodData d) { + this(d, new MethodEditor(d)); + } + + public class UnoptimizableCodeException extends Exception { + private static final long serialVersionUID = 2543170335674010642L; + + public UnoptimizableCodeException(String s) { + super(s); + } + } + + public int findUniqueStackDef(int instr, int stack) throws UnoptimizableCodeException { + instructions = editor.getInstructions(); + handlers = editor.getHandlers(); + checkConsistentStackSizes(); + buildBackEdges(); + buildStackDefMap(); + + return uniqueStackDefLocations[instr][stack]; + } + + public void optimize() throws UnoptimizableCodeException { + boolean changed; + do { + instructions = editor.getInstructions(); + handlers = editor.getHandlers(); + checkConsistentStackSizes(); + buildBackEdges(); + + editor.beginPass(); + buildStackDefMap(); + pushBackLocalStores(); + forwardDups(); + changed = editor.applyPatches(); + editor.endPass(); + } while (changed); + } + + private void buildBackEdges() { + int[] backEdgeCount = new int[instructions.length]; + + for (int i = 0; i < instructions.length; i++) { + int[] targets = instructions[i].getBranchTargets(); + for (int j = 0; j < targets.length; j++) { + backEdgeCount[targets[j]]++; + } + ExceptionHandler[] hs = handlers[i]; + for (int j = 0; j < hs.length; j++) { + backEdgeCount[hs[j].getHandler()]++; + } + } + + backEdges = new int[instructions.length][]; + for (int i = 0; i < backEdges.length; i++) { + if (backEdgeCount[i] > 0) { + backEdges[i] = new int[backEdgeCount[i]]; + } else { + backEdges[i] = noEdges; + } + } + Arrays.fill(backEdgeCount, 0); + + for (int i = 0; i < instructions.length; i++) { + int[] targets = instructions[i].getBranchTargets(); + for (int j = 0; j < targets.length; j++) { + int target = targets[j]; + backEdges[target][backEdgeCount[target]] = i; + backEdgeCount[target]++; + } + ExceptionHandler[] hs = handlers[i]; + for (int j = 0; j < hs.length; j++) { + int target = hs[j].getHandler(); + backEdges[target][backEdgeCount[target]] = i; + backEdgeCount[target]++; + } + } + } + + private int checkConsistentStackSizes() throws UnoptimizableCodeException { + stackSizes = new int[instructions.length]; + Arrays.fill(stackSizes, -1); + + checkStackSizesAt(0, 0); + + int result = 0; + for (int i = 0; i < stackSizes.length; i++) { + result = Math.max(result, stackSizes[i]); + } + return result; + } + + private void checkStackSizesAt(int instruction, int stackSize) throws UnoptimizableCodeException { + while (true) { + if (instruction < 0 || instruction >= instructions.length) { + throw new UnoptimizableCodeException("Code exits in an illegal way"); + } + if (stackSizes[instruction] != -1) { + if (stackSizes[instruction] != stackSize) { + throw new UnoptimizableCodeException("Mismatched stack sizes at " + instruction + ": " + stackSize + " and " + + stackSizes[instruction]); + } else { + return; + } + } + stackSizes[instruction] = stackSize; + + Instruction instr = instructions[instruction]; + stackSize -= instr.getPoppedCount(); + if (stackSize < 0) { + throw new UnoptimizableCodeException("Stack underflow at " + instruction); + } + if (instr instanceof DupInstruction) { + DupInstruction d = (DupInstruction) instr; + stackSize += d.getSize() + d.getPoppedCount(); + } else if (instr.getPushedType(null) != null) { + stackSize++; + } + + int[] targets = instr.getBranchTargets(); + for (int i = 0; i < targets.length; i++) { + checkStackSizesAt(targets[i], stackSize); + } + + ExceptionHandler[] hs = handlers[instruction]; + for (int i = 0; i < hs.length; i++) { + checkStackSizesAt(hs[i].getHandler(), 1); + } + + if (!instr.isFallThrough()) { + return; + } + + instruction++; + } + } + + private static boolean instructionKillsVar(Instruction instr, int v) { + if (instr instanceof StoreInstruction) { + StoreInstruction st = (StoreInstruction) instr; + return st.getVarIndex() == v || (Util.getWordSize(st.getType()) == 2 && st.getVarIndex() + 1 == v); + } else { + return false; + } + } + + private void forwardDups() { + for (int i = 0; i < instructions.length; i++) { + Instruction instr = instructions[i]; + if (instr instanceof DupInstruction && ((DupInstruction) instr).getDelta() == 0 && uniqueStackDefLocations[i][0] >= 0 + && instructions[uniqueStackDefLocations[i][0]] instanceof LoadInstruction) { + int source = uniqueStackDefLocations[i][0]; + final LoadInstruction li = (LoadInstruction) instructions[source]; + + for (int j = 0; j < instructions.length; j++) { + int[] locs = uniqueStackDefLocations[j]; + if (locs[0] == i) { + // check to see if the variable is killed along any path from the + // dup + // to its use + BitSet path = getInstructionsOnPath(source, j); + boolean killed = false; + int v = li.getVarIndex(); + for (int k = 0; j < instructions.length && !killed; k++) { + if (path.get(k)) { + if (instructionKillsVar(instructions[k], v)) { + killed = true; + } + } + } + + if (!killed) { + editor.insertBefore(j, new MethodEditor.Patch() { + public void emitTo(Output w) { + w.emit(PopInstruction.make(1)); + w.emit(li); + } + }); + } + } + } + } + } + } + + private void pushBackLocalStores() { + for (int i = 0; i < instructions.length; i++) { + Instruction instr = instructions[i]; + if (instr instanceof StoreInstruction && uniqueStackDefLocations[i][0] >= 0 && uniqueStackDefLocations[i][0] != i - 1 + && uniqueStackUseLocations[uniqueStackDefLocations[i][0]] == i) { + final StoreInstruction s = (StoreInstruction) instr; + int source = uniqueStackDefLocations[i][0]; + + // Check if the path from source to i contains anything killing the + // variable + BitSet path = getInstructionsOnPath(source, i); + boolean killed = false; + int v = s.getVarIndex(); + for (int j = 0; j < instructions.length && !killed; j++) { + if (path.get(j)) { + if (instructionKillsVar(instructions[j], v)) { + killed = true; + } + } + } + + if (killed) { + final String type = s.getType(); + final int newVar = LocalAllocator.allocate(data, type); + // put a store to the newVar right after the source + editor.insertAfter(source, new MethodEditor.Patch() { + public void emitTo(Output w) { + w.emit(StoreInstruction.make(type, newVar)); + } + }); + // load newVar before storing to correct variable + editor.insertBefore(i, new MethodEditor.Patch() { + public void emitTo(Output w) { + w.emit(LoadInstruction.make(type, newVar)); + } + }); + } else { + // remove store instruction + editor.replaceWith(i, new MethodEditor.Patch() { + public void emitTo(Output w) { + } + }); + // replace it right after the source + editor.insertAfter(source, new MethodEditor.Patch() { + public void emitTo(Output w) { + w.emit(s); + } + }); + } + } + } + } + + private void buildStackDefMap() { + int[][] abstractStacks = new int[instructions.length][]; + + for (int i = 0; i < instructions.length; i++) { + abstractStacks[i] = new int[stackSizes[i]]; + Arrays.fill(abstractStacks[i], -2); + } + + for (int i = 0; i < instructions.length; i++) { + if (instructions[i] instanceof DupInstruction) { + DupInstruction d = (DupInstruction) instructions[i]; + for (int j = 0; j < 2 * d.getSize() + d.getDelta(); j++) { + followStackDef(abstractStacks, i, i + 1, stackSizes[i + 1] - 1 - j); + } + } else if (instructions[i].getPushedType(null) != null) { + followStackDef(abstractStacks, i, i + 1, stackSizes[i + 1] - 1); + } + } + + uniqueStackDefLocations = new int[instructions.length][]; + for (int i = 0; i < instructions.length; i++) { + uniqueStackDefLocations[i] = new int[instructions[i].getPoppedCount()]; + int popped = instructions[i].getPoppedCount(); + System.arraycopy(abstractStacks[i], stackSizes[i] - popped, uniqueStackDefLocations[i], 0, popped); + } + + uniqueStackUseLocations = new int[instructions.length]; + Arrays.fill(uniqueStackUseLocations, -2); + + for (int i = 0; i < instructions.length; i++) { + abstractStacks[i] = new int[stackSizes[i]]; + Arrays.fill(abstractStacks[i], -2); + } + + for (int i = 0; i < instructions.length; i++) { + int count = instructions[i].getPoppedCount(); + if (count == 1) { + followStackUse(abstractStacks, i, i, stackSizes[i] - 1); + } else if (count > 1) { + for (int j = 0; j < count; j++) { + followStackUse(abstractStacks, -1, i, stackSizes[i] - 1 - j); + } + } + } + + for (int i = 0; i < instructions.length; i++) { + if (instructions[i].getPushedType(null) != null) { + uniqueStackUseLocations[i] = abstractStacks[i + 1][stackSizes[i + 1] - 1]; + } + } + } + + private void followStackDef(int[][] abstractDefStacks, int def, int instruction, int stackPointer) { + while (true) { + int[] stack = abstractDefStacks[instruction]; + if (stackPointer >= stack.length) { + // the value must have been popped off by the last instruction + return; + } + + if (stack[stackPointer] == -2) { + stack[stackPointer] = def; + } else if (stack[stackPointer] == def) { + return; + } else if (stack[stackPointer] == -1) { + return; + } else { + stack[stackPointer] = -1; + def = -1; + } + + int[] targets = instructions[instruction].getBranchTargets(); + for (int i = 0; i < targets.length; i++) { + followStackDef(abstractDefStacks, def, targets[i], stackPointer); + } + + ExceptionHandler[] hs = handlers[instruction]; + for (int i = 0; i < hs.length; i++) { + followStackDef(abstractDefStacks, -1, hs[i].getHandler(), 0); + } + + if (!instructions[instruction].isFallThrough()) { + return; + } + instruction++; + } + } + + private void followStackUse(int[][] abstractUseStacks, int use, int instruction, int stackPointer) { + while (true) { + int[] stack = abstractUseStacks[instruction]; + if (stackPointer >= stack.length) { + // the value must have been pushed by this instruction + return; + } + + if (stack[stackPointer] == -2) { + stack[stackPointer] = use; + } else if (stack[stackPointer] == use || stack[stackPointer] == -1) { + return; + } else { + stack[stackPointer] = -1; + use = -1; + } + + int[] back = backEdges[instruction]; + for (int i = 0; i < back.length; i++) { + followStackUse(abstractUseStacks, use, back[i], stackPointer); + } + + if (instruction == 0 || !instructions[instruction - 1].isFallThrough()) { + return; + } + instruction--; + } + } + + private BitSet getInstructionsOnPath(int from, int to) { + BitSet reachable = new BitSet(); + getReachableInstructions(reachable, from, to); + BitSet reaching = new BitSet(); + getReachingInstructions(reaching, from, to); + reachable.and(reaching); + return reachable; + } + + private void getReachableInstructions(BitSet bits, int from, int to) { + while (true) { + if (from == to) { + return; + } + + bits.set(from); + + int[] targets = instructions[from].getBranchTargets(); + for (int i = 0; i < targets.length; i++) { + getReachableInstructions(bits, targets[i], to); + } + + if (!instructions[from].isFallThrough()) { + return; + } + from++; + } + } + + private void getReachingInstructions(BitSet bits, int from, int to) { + while (true) { + if (to == from) { + return; + } + + bits.set(to); + + int[] targets = backEdges[to]; + for (int i = 0; i < targets.length; i++) { + getReachingInstructions(bits, from, targets[i]); + } + + if (to == 0 || !instructions[to - 1].isFallThrough()) { + return; + } + to--; + } + } +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/tools/OfflineInstrumenterBase.java b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/tools/OfflineInstrumenterBase.java new file mode 100644 index 000000000..cd9dbbea6 --- /dev/null +++ b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeBT/tools/OfflineInstrumenterBase.java @@ -0,0 +1,581 @@ +/******************************************************************************* + * 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.shrikeBT.tools; + +import java.io.BufferedInputStream; +import java.io.BufferedOutputStream; +import java.io.BufferedReader; +import java.io.File; +import java.io.FileFilter; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.BitSet; +import java.util.Enumeration; +import java.util.HashSet; +import java.util.jar.JarEntry; +import java.util.jar.JarFile; +import java.util.jar.JarOutputStream; +import java.util.zip.ZipEntry; + +/** + * This class provides functionality for performing offline instrumentation. It + * is subclassed with class-toolkit-specific functionality. + */ +public abstract class OfflineInstrumenterBase { + private int inputIndex; + private HashSet entryNames = new HashSet(); + private ArrayList inputs = new ArrayList(); + private BitSet ignoringInputs = new BitSet(); + private File outputFile; + private boolean passUnmodifiedClasses = false; + + private JarOutputStream outputJar; + + private JarFile cachedJar; + private File cachedJarFile; + + private ManifestBuilder manifestBuilder; + + /** + * This installs a ManifestBuilder callback that this class will notify + * whenever an entry has been added to the output zip file. + */ + public void setManifestBuilder(ManifestBuilder mb) { + manifestBuilder = mb; + } + + /** + * Thiscallback is notified whenever an entry has been added to the output zip + * file. + */ + public static interface ManifestBuilder { + public void addEntry(ZipEntry ze); + } + + /** + * This class represents a resource which can be opened and read; either a + * file or a JAR entry. + */ + abstract class Input { + private String className; + + /** + * Tell us what the classname is supposed to be, if it's a class file. + */ + public final void setClassName(String c) { + className = c.intern(); + } + + /** + * Returns the classname if it has been set. + */ + public final String getClassName() { + return className; + } + + /** + * Open the resource for reading as a stream. + */ + public abstract InputStream open() throws IOException; + + /** + * @return true if this resource represents a class, false otherwise + */ + public boolean isClass() { + return true; + } + } + + /** + * This class represents a JAR file entry. It might or might not be a class; + * we support non-class JAR resources so that we can copy them to the output + * JAR if the client requests that. + */ + final class JarInput extends Input { + private File file; + private String name; + + /** + * Select a particular entry from a JAR file on disk. + */ + public JarInput(File f, String je) { + file = f; + name = je; + } + + public InputStream open() throws IOException { + JarFile cachedJar = openCachedJar(file); + return cachedJar.getInputStream(cachedJar.getEntry(name)); + } + + public String toString() { + return file.getPath() + "#" + name; + } + + public boolean isClass() { + return name.endsWith(".class"); + } + + /** + * Get the underlying ZipEntry corresponding to this resource. + */ + public ZipEntry getEntry() throws IOException { + JarFile cachedJar = openCachedJar(file); + return cachedJar.getEntry(name); + } + } + + /** + * Open a JAR/ZIP file. This routine caches the last JAR file opened to save + * effort when the same file is accessed again and again. DO NOT close the + * file returned by this routine until you've finished with this + * OfflineInstrumente completely. Also, this JarFile will be closed the next + * time someone calls openCachedJar. + */ + private JarFile openCachedJar(File file) throws IOException { + if (cachedJarFile != null && cachedJarFile.equals(file)) { + return cachedJar; + } else { + if (cachedJar != null) { + cachedJar.close(); + } + cachedJarFile = file; + cachedJar = new JarFile(file); + return cachedJar; + } + } + + /** + * This class represents a plain old class file in the filesystem. Non-class + * file resources are not supported. + */ + final class ClassInput extends Input { + private File file; + + public ClassInput(File f) { + file = f; + } + + public InputStream open() throws IOException { + return new FileInputStream(file); + } + + public String toString() { + return file.getPath(); + } + } + + protected OfflineInstrumenterBase() { + } + + /** + * Set the file in which instrumented classes will be deposited. + */ + final public void setOutputJar(File f) { + outputFile = f; + } + + /** + * Indicate whether classes which are not modified will be put into the output + * jar anyway. + */ + final public void setPassUnmodifiedClasses(boolean pass) { + passUnmodifiedClasses = pass; + } + + /** + * Add a JAR file containing source classes to instrument. + */ + final public void addInputJar(File f) throws IOException { + JarFile jf = new JarFile(f); + for (Enumeration e = jf.entries(); e.hasMoreElements();) { + JarEntry entry = (JarEntry) e.nextElement(); + if (!entry.isDirectory()) { + String name = entry.getName(); + inputs.add(new JarInput(f, name)); + } + } + jf.close(); + } + + /** + * Add a JAR entry containing a source class to instrument. + */ + final public void addInputJarEntry(File f, String name) throws IOException { + inputs.add(new JarInput(f, name)); + } + + /** + * Add a class file containing a source class to instrument. + */ + final public void addInputClass(File f) { + inputs.add(new ClassInput(f)); + } + + /** + * Add a directory containing class files to instrument. All subdirectories + * are also scanned. + */ + final public void addInputDirectory(File d) throws IOException { + File[] fs = d.listFiles(new FileFilter() { + public boolean accept(File f) { + return f.isDirectory() || f.getName().endsWith(".class"); + } + }); + for (int i = 0; i < fs.length; i++) { + File f = fs[i]; + if (f.isDirectory()) { + addInputDirectory(f); + } else { + addInputClass(f); + } + } + } + + /** + * Add something to instrument --- the name of a JAR file, a class file, a + * directory or an entry within a jar file (as filename#entryname). If we + * can't identify it, nothing is added and we return false. + */ + final public boolean addInputElement(String a) throws IOException { + try { + int poundIndex = a.indexOf('#'); + if (poundIndex > 0) { + addInputJarEntry(new File(a.substring(0, poundIndex)), a.substring(poundIndex + 1)); + return true; + } + File f = new File(a); + if (f.isDirectory()) { + addInputDirectory(f); + return true; + } else if (f.exists()) { + if (a.endsWith(".class")) { + addInputClass(f); + return true; + } else if (a.endsWith(".jar") || a.endsWith(".zip")) { + addInputJar(new File(a)); + return true; + } + } + } catch (IOException ex) { + throw new IOException("Error reading input element '" + a + "': " + ex.getMessage()); + } + return false; + } + + /** + * Parse an argument list to find elements to instrument and the name of the + * output file. The "-o filename" option selects the output JAR file name. Any + * other argument not starting with "-" is added to the list of elements to + * instrument, if it appears to be the name of a class file, JAR file, or + * directory. If any argument starting with "--" is encountered, the rest of + * the command-line is considered leftover + * + * @return the arguments that were not understood + */ + final public String[] parseStandardArgs(String[] args) throws IOException { + ArrayList leftover = new ArrayList(); + + for (int i = 0; i < args.length; i++) { + String a = args[i]; + if (a.equals("-o") && i + 1 < args.length) { + setOutputJar(new File(args[i + 1])); + i++; + continue; + } else if (!a.startsWith("-")) { + if (addInputElement(a)) { + continue; + } + } else if (a.startsWith("--")) { + for (int j = i; j < args.length; j++) { + leftover.add(args[j]); + } + break; + } + leftover.add(a); + } + + String[] r = new String[leftover.size()]; + leftover.toArray(r); + return r; + } + + /** + * @return the number of source classes to be instrumented + */ + final public int getNumInputClasses() { + return inputs.size(); + } + + /** + * Read a list of class file names from a stream and add them to the list of + * things to instrument. + */ + final public void readInputClasses(InputStream s) throws IOException { + String str; + BufferedReader r = new BufferedReader(new InputStreamReader(s)); + while ((str = r.readLine()) != null) { + addInputElement(str); + } + } + + /** + * Start traversing the source class list from the beginning. + */ + final public void beginTraversal() { + inputIndex = 0; + } + + protected abstract Object makeClassFromStream(BufferedInputStream s) throws IOException; + + protected abstract String getClassName(Object cl); + + protected abstract void writeClassTo(Object cl, Object mods, OutputStream s) throws IOException; + + final protected Object internalNextClass() throws IOException { + while (true) { + if (inputIndex >= inputs.size()) { + return null; + } else { + Input in = inputs.get(inputIndex); + inputIndex++; + if (ignoringInputs.get(inputIndex - 1) || !in.isClass()) { + continue; + } + BufferedInputStream s = new BufferedInputStream(in.open()); + try { + Object r = makeClassFromStream(s); + String name = getClassName(r); + in.setClassName(name); + return r; + } finally { + s.close(); + } + } + } + } + + private static String toEntryName(String className) { + return className.replace('.', '/') + ".class"; + } + + /** + * Get the name of the resource containing the last class returned. This is + * either a file name (e.g., "com/ibm/Main.class"), or a JAR entry name (e.g., + * "apps/app.jar#com/ibm/Main.class"). + * + * @return the resource name, or null if no class has been returned yet + */ + final public String getLastClassResourceName() { + if (inputIndex < 1) { + return null; + } else { + Input in = inputs.get(inputIndex - 1); + return in.toString(); + } + } + + /** + * Returns the File we are storing classes into. + */ + final public File getOutputFile() { + return outputFile; + } + + final protected boolean internalOutputModifiedClass(Object cf, Object mods) throws IOException { + makeOutputJar(); + String name = toEntryName(getClassName(cf)); + if (entryNames.contains(name)) { + return false; + } else { + putNextEntry(new ZipEntry(name)); + BufferedOutputStream s = new BufferedOutputStream(outputJar); + writeClassTo(cf, mods, s); + s.flush(); + outputJar.closeEntry(); + return true; + } + } + + /** + * Set the JAR Comment for the output JAR. + */ + final public void setJARComment(String comment) throws IOException { + makeOutputJar(); + outputJar.setComment(comment); + } + + final void makeOutputJar() throws IOException { + if (outputJar == null) { + if (outputFile == null) { + throw new IllegalArgumentException("Output file was not set"); + } + + outputJar = new JarOutputStream(new FileOutputStream(outputFile)); + } + } + + /** + * Skip the last class returned in every future traversal of the class list. + */ + final public void setIgnore(boolean ignore) { + if (inputIndex == 0) { + throw new IllegalArgumentException("Must get a class before ignoring it"); + } + + ignoringInputs.set(inputIndex - 1); + } + + private static byte[] cachedBuf; + + private static synchronized byte[] makeBuf() { + if (cachedBuf != null) { + byte[] r = cachedBuf; + cachedBuf = null; + return r; + } else { + return new byte[60000]; + } + } + + private static synchronized void releaseBuf(byte[] buf) { + cachedBuf = buf; + } + + public static void copyStream(InputStream in, OutputStream out) throws IOException { + byte[] buf = makeBuf(); + try { + while (true) { + int read = in.read(buf); + if (read < 0) { + return; + } + out.write(buf, 0, read); + } + } finally { + releaseBuf(buf); + } + } + + /** + * Add a raw ZipEntry to the output JAR. Call endOutputJarEntry() when you're + * done. + * + * @return the OutputStream to be used to write the entry contents + */ + final public OutputStream addOutputJarEntry(ZipEntry ze) throws IOException { + putNextEntry(ze); + return outputJar; + } + + /** + * Complete and flush the entry initiated by addOutputJarEntry. + */ + final public void endOutputJarEntry() throws IOException { + outputJar.closeEntry(); + } + + /** + * Call this to copy any unmodified classes to the output. This is called + * automatically by close(); you should only call this if you want to write an + * entry to the JAR file *after* the unmodified classes. This will only ever + * be called once per output JAR. + */ + final public void writeUnmodifiedClasses() throws IOException { + passUnmodifiedClasses = false; + makeOutputJar(); + for (int i = 0; i < inputs.size(); i++) { + Input in = inputs.get(i); + if (!in.isClass()) { + if (in instanceof JarInput) { + JarInput jin = (JarInput) in; + ZipEntry entry = jin.getEntry(); + InputStream s = jin.open(); + try { + ZipEntry newEntry = new ZipEntry(entry.getName()); + newEntry.setComment(entry.getComment()); + newEntry.setExtra(entry.getExtra()); + newEntry.setTime(entry.getTime()); + putNextEntry(newEntry); + copyStream(s, outputJar); + outputJar.closeEntry(); + } finally { + s.close(); + } + } else { + throw new Error("Unknown non-class input: " + in); + } + } else { + String name = in.getClassName(); + if (name == null) { + BufferedInputStream s = new BufferedInputStream(in.open(), 65536); + try { + Object cl = makeClassFromStream(s); + String entryName = toEntryName(getClassName(cl)); + if (!entryNames.contains(entryName)) { + putNextEntry(new ZipEntry(entryName)); + BufferedOutputStream clOut = new BufferedOutputStream(outputJar); + writeClassTo(cl, null, clOut); + clOut.flush(); + outputJar.closeEntry(); + } + } finally { + s.close(); + } + } else { + String entryName = toEntryName(name); + if (!entryNames.contains(entryName)) { + BufferedInputStream s = new BufferedInputStream(in.open()); + try { + putNextEntry(new ZipEntry(entryName)); + BufferedOutputStream clOut = new BufferedOutputStream(outputJar); + copyStream(s, clOut); + clOut.flush(); + outputJar.closeEntry(); + } finally { + s.close(); + } + } + } + } + } + } + + /** + * Call this when you're done modifying classes. + */ + final public void close() throws IOException { + if (passUnmodifiedClasses) { + writeUnmodifiedClasses(); + } + + if (outputJar != null) { + outputJar.close(); + } + + if (cachedJar != null) { + cachedJar.close(); + } + } + + private void putNextEntry(ZipEntry newEntry) throws IOException { + outputJar.putNextEntry(newEntry); + entryNames.add(newEntry.getName()); + if (manifestBuilder != null) { + manifestBuilder.addEntry(newEntry); + } + } +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/src/com/ibm/wala/shrikeCT/ClassConstants.java b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeCT/ClassConstants.java new file mode 100644 index 000000000..e6f41e1d9 --- /dev/null +++ b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeCT/ClassConstants.java @@ -0,0 +1,45 @@ +/******************************************************************************* + * 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.shrikeCT; + +/** + * This interface defines class file constants used by ShrikeCT. The names and + * values are taken directly from the JVM spec. + */ +public interface ClassConstants { + public static final int MAGIC = 0xCAFEBABE; + + public static final byte CONSTANT_Utf8 = 1; + public static final byte CONSTANT_Integer = 3; + public static final byte CONSTANT_Float = 4; + public static final byte CONSTANT_Long = 5; + public static final byte CONSTANT_Double = 6; + public static final byte CONSTANT_Class = 7; + public static final byte CONSTANT_String = 8; + public static final byte CONSTANT_FieldRef = 9; + public static final byte CONSTANT_MethodRef = 10; + public static final byte CONSTANT_InterfaceMethodRef = 11; + public static final byte CONSTANT_NameAndType = 12; + + public static final short ACC_PUBLIC = 0x1; + public static final short ACC_PRIVATE = 0x2; + public static final short ACC_PROTECTED = 0x4; + public static final short ACC_STATIC = 0x8; + public static final short ACC_FINAL = 0x10; + public static final short ACC_SYNCHRONIZED = 0x20; + public static final short ACC_SUPER = 0x20; + public static final short ACC_VOLATILE = 0x40; + public static final short ACC_TRANSIENT = 0x80; + public static final short ACC_NATIVE = 0x100; + public static final short ACC_INTERFACE = 0x200; + public static final short ACC_ABSTRACT = 0x400; + public static final short ACC_STRICT = 0x800; +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/src/com/ibm/wala/shrikeCT/ClassReader.java b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeCT/ClassReader.java new file mode 100644 index 000000000..3b36c84a1 --- /dev/null +++ b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeCT/ClassReader.java @@ -0,0 +1,664 @@ +/******************************************************************************* + * 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.shrikeCT; + +/** + * This is the core class for reading class file data. + * + * ClassReader performs lazy parsing, and thus most of the methods can throw an + * InvalidClassFileException. + */ +public final class ClassReader implements ClassConstants { + private byte[] bytes; + private int[] methodOffsets; + private int[] fieldOffsets; + private ConstantPoolParser cpParser; + private int classInfoOffset; + private int attrInfoOffset; + private int interfaceCount; + + /** + * Build a reader. + * + * If the class file data is corrupt an exception might not be thrown + * immediately. Instead an exception might be thrown later, during the + * execution of some access method. This is a consequence of the 'lazy + * parsing' performed by ClassReader. + * + * @param bytes + * the class file data + * @throws InvalidClassFileException + * the class file data is corrupt + */ + public ClassReader(byte[] bytes) throws InvalidClassFileException { + this.bytes = bytes; + parse(); + } + + private void checkLength(int offset, int required) throws InvalidClassFileException { + if (bytes.length < offset + required) { + throw new InvalidClassFileException(offset, "file truncated, expected " + required + " bytes, saw only " + + (bytes.length - offset)); + } + } + + private void parse() throws InvalidClassFileException { + int offset = 0; + + checkLength(offset, 10); + int magic = getInt(offset); + int minorVersion = getUShort(offset + 4); + int majorVersion = getUShort(offset + 6); + int constantPoolCount = getUShort(offset + 8); + offset += 10; + + if (magic != MAGIC) { + throw new InvalidClassFileException(offset, "bad magic number: " + magic); + } + if (majorVersion < 45 || majorVersion > 49) { + throw new InvalidClassFileException(offset, "unknown class file version: " + majorVersion + "." + minorVersion); + } + + cpParser = new ConstantPoolParser(bytes, offset, constantPoolCount); + offset += cpParser.getRawSize(); + + classInfoOffset = offset; + checkLength(offset, 8); + // int accessFlags = getUShort(offset); + // int thisClass = getUShort(offset + 2); + // int superClass = getUShort(offset + 4); + interfaceCount = getUShort(offset + 6); + if (interfaceCount < 0) { + throw new InvalidClassFileException(offset, "negative interface count: " + interfaceCount); + } + offset += 8; + checkLength(offset, interfaceCount * 2); + offset += interfaceCount * 2; + + checkLength(offset, 2); + int fieldCount = getUShort(offset); + if (fieldCount < 0) { + throw new InvalidClassFileException(offset, "negative field count: " + interfaceCount); + } + offset = parseFields(offset + 2, fieldCount); + + checkLength(offset, 2); + int methodCount = getUShort(offset); + if (methodCount < 0) { + throw new InvalidClassFileException(offset, "negative method count: " + interfaceCount); + } + offset = parseMethods(offset + 2, methodCount); + + attrInfoOffset = offset; + checkLength(offset, 2); + int attrCount = getUShort(offset); + offset = skipAttributes(offset + 2, attrCount); + + if (offset != bytes.length) { + throw new InvalidClassFileException(offset, "extra data in class file"); + } + } + + private int skipAttributes(int offset, int count) throws InvalidClassFileException { + if (count < 0) { + throw new InvalidClassFileException(offset, "negative attribute count: " + interfaceCount); + } + + for (int i = 0; i < count; i++) { + checkLength(offset, 6); + int size = getInt(offset + 2); + if (size < 0) { + throw new InvalidClassFileException(offset, "negative attribute size: " + size); + } + offset += 6; + checkLength(offset, size); + offset += size; + } + return offset; + } + + private int parseFields(int offset, int count) throws InvalidClassFileException { + fieldOffsets = new int[count + 1]; + for (int i = 0; i < count; i++) { + fieldOffsets[i] = offset; + checkLength(offset, 8); + offset = skipAttributes(offset + 8, getUShort(offset + 6)); + } + fieldOffsets[count] = offset; + return offset; + } + + private int parseMethods(int offset, int count) throws InvalidClassFileException { + methodOffsets = new int[count + 1]; + for (int i = 0; i < count; i++) { + methodOffsets[i] = offset; + checkLength(offset, 8); + offset = skipAttributes(offset + 8, getUShort(offset + 6)); + } + methodOffsets[count] = offset; + return offset; + } + + /** + * @return the raw class data bytes + */ + public byte[] getBytes() { + return bytes; + } + + /** + * @return the magic number at the start of the class file. + */ + public int getMagic() { + return getInt(0); + } + + /** + * @return the minor version of the class file + */ + public int getMinorVersion() { + return getUShort(4); + } + + /** + * @return the major version of the class file + */ + public int getMajorVersion() { + return getUShort(6); + } + + /** + * @return the access flags for the class + */ + public int getAccessFlags() { + return getUShort(classInfoOffset); + } + + /** + * @return the index of the constant pool entry for the class name + */ + public int getNameIndex() { + return getUShort(classInfoOffset + 2); + } + + String getClassFromAddress(int addr) throws InvalidClassFileException { + int c = getUShort(addr); + if (c == 0) { + return null; + } else { + try { + return cpParser.getCPClass(c); + } catch (IllegalArgumentException ex) { + throw new InvalidClassFileException(addr, "Invalid class constant pool index: " + c); + } + } + } + + /** + * @return the name of the class in JVM format (e.g., java/lang/Object) + */ + public String getName() throws InvalidClassFileException { + String s = getClassFromAddress(classInfoOffset + 2); + if (s == null) { + throw new InvalidClassFileException(classInfoOffset + 2, "Null class name not allowed"); + } else { + return s; + } + } + + /** + * @return the constant pool index of the superclass name, or 0 if this is + * java.lang.Object + */ + public int getSuperNameIndex() { + return getUShort(classInfoOffset + 4); + } + + /** + * @return the superclass name in JVM format (e.g., java/lang/Object), or null + * if this class is java.lang.Object + */ + public String getSuperName() throws InvalidClassFileException { + return getClassFromAddress(classInfoOffset + 4); + } + + /** + * @return the number of interfaces this class implements + */ + public int getInterfaceCount() { + return interfaceCount; + } + + private void verifyInterfaceIndex(int i) { + if (i < 0 || i >= interfaceCount) { + throw new IllegalArgumentException("Invalid interface index: " + i); + } + } + + /** + * @return the constant pool index of the name of the i'th implemented + * interface + */ + public int getInterfaceNameIndex(int i) { + verifyInterfaceIndex(i); + return getUShort(classInfoOffset + 8 + 2 * i); + } + + /** + * @return an array of the constant pool indices for the names of the + * implemented interfaces + */ + public int[] getInterfaceNameIndices() { + int[] indices = new int[interfaceCount]; + for (int i = 0; i < interfaceCount; i++) { + indices[i] = getUShort(classInfoOffset + 8 + 2 * i); + } + return indices; + } + + /** + * @return the name of the i'th implemented interface + */ + public String getInterfaceName(int i) throws InvalidClassFileException { + verifyInterfaceIndex(i); + String s = getClassFromAddress(classInfoOffset + 8 + 2 * i); + if (s == null) { + throw new InvalidClassFileException(classInfoOffset + 8 + 2 * i, "Null interface name not allowed"); + } else { + return s; + } + } + + /** + * @return an array of the names of the implemented interfaces + */ + public String[] getInterfaceNames() throws InvalidClassFileException { + String[] names = new String[interfaceCount]; + for (int i = 0; i < interfaceCount; i++) { + String s = getClassFromAddress(classInfoOffset + 8 + 2 * i); + if (s == null) { + throw new InvalidClassFileException(classInfoOffset + 8 + 2 * i, "Null interface name not allowed"); + } + names[i] = s; + } + return names; + } + + /** + * This method allows direct read-only access to the constant pool for the + * class. + * + * @return the constant pool for the class + */ + public ConstantPoolParser getCP() { + return cpParser; + } + + /** + * @return the signed 32-bit value at offset i in the class data + */ + public int getInt(int i) { + return (bytes[i] << 24) + ((bytes[i + 1] & 0xFF) << 16) + ((bytes[i + 2] & 0xFF) << 8) + (bytes[i + 3] & 0xFF); + } + + /** + * @return the unsigned 16-bit value at offset i in the class data + */ + public int getUShort(int i) { + return ((bytes[i] & 0xFF) << 8) + (bytes[i + 1] & 0xFF); + } + + /** + * @return the signed 16-bit value at offset i in the class data + */ + public int getShort(int i) { + return (bytes[i] << 8) + (bytes[i + 1] & 0xFF); + } + + /** + * @return the signed 8-bit value at offset i in the class data + */ + public byte getByte(int i) { + return bytes[i]; + } + + /** + * @return the number of fields in the class + */ + public int getFieldCount() { + return fieldOffsets.length - 1; + } + + private void verifyFieldIndex(int f) { + if (f < 0 || f >= fieldOffsets.length - 1) { + throw new IllegalArgumentException("Invalid field index: " + f); + } + } + + /** + * @return the access flags for the f'th field + */ + public int getFieldAccessFlags(int f) { + verifyFieldIndex(f); + return getUShort(fieldOffsets[f]); + } + + String getUtf8FromAddress(int addr) throws InvalidClassFileException { + int s = getUShort(addr); + if (s == 0) { + return null; + } else { + try { + return cpParser.getCPUtf8(s); + } catch (IllegalArgumentException ex) { + throw new InvalidClassFileException(addr, "Invalid Utf8 constant pool index: " + s); + } + } + } + + /** + * @return the name of the f'th field + */ + public String getFieldName(int f) throws InvalidClassFileException { + verifyFieldIndex(f); + return getUtf8FromAddress(fieldOffsets[f] + 2); + } + + /** + * @return the type of the f'th field, in JVM format (e.g., I, Z, + * java/lang/Object) + */ + public String getFieldType(int f) throws InvalidClassFileException { + verifyFieldIndex(f); + return getUtf8FromAddress(fieldOffsets[f] + 4); + } + + /** + * @return the index of the constant pool entry for the name of the f'th + * field, in JVM format (e.g., I, Z, Ljava/lang/Object;) + */ + public int getFieldNameIndex(int f) { + verifyFieldIndex(f); + return getUShort(fieldOffsets[f] + 2); + } + + /** + * @return the index of the constant pool entry for the type of the f'th + * field, in JVM format (e.g., I, Z, Ljava/lang/Object;) + */ + public int getFieldTypeIndex(int f) { + verifyFieldIndex(f); + return getUShort(fieldOffsets[f] + 4); + } + + /** + * AttrIterator provides access to attributes in the class file. + * + * AttrIterators can be reused for many different iterations, like this: + * + *
                              +   *   AttrIterator iter = new AttrIterator();
                              +   *    int fieldCount = reader.getFieldCount();
                              +   *    for (int i = 0; i < fieldCount; i++) {
                              +   *      reader.initFieldAttributeIterator(i, iter);
                              +   *      for (; iter.isValid(); iter.advance()) {
                              +   *        if (iter.getName().equals("ConstantValue")) {
                              +   *          ConstantValueReader cv = new ConstantValueReader(iter);
                              +   *          ...
                              +   *        }
                              +   *      }
                              +   *    }
                              +   * 
                              + */ + public static final class AttrIterator { + ClassReader cr; + int offset; + int size; + private int remaining; + + /** + * Create a blank iterator. The iterator is not valid until it is + * initialized by some other class. + */ + public AttrIterator() { + } + + private void setSize() { + if (remaining > 0) { + size = 6 + cr.getInt(offset + 2); + } + } + + void init(ClassReader cr, int offset) { + this.cr = cr; + this.offset = offset + 2; + this.remaining = cr.getUShort(offset); + setSize(); + } + + void verifyValid() { + if (remaining <= 0) { + throw new IllegalArgumentException("Attempt to manipulate invalid AttrIterator"); + } + } + + public ClassReader getClassReader() { + verifyValid(); + return cr; + } + + /** + * The attribute iterator must be valid. + * + * @return the offset of the raw attribute data (including attribute header) + * in the class file data + */ + public int getRawOffset() { + verifyValid(); + return offset; + } + + /** + * The attribute iterator must be valid. + * + * @return the size of the raw attribute data (including attribute header) + * in the class file data + */ + public int getRawSize() { + verifyValid(); + return size; + } + + /** + * The attribute iterator must be valid. + * + * @return the offset of the attribute data (excluding attribute header) in + * the class file data + */ + public int getDataOffset() { + verifyValid(); + return offset + 6; + } + + /** + * The attribute iterator must be valid. + * + * @return the size of the attribute data (excluding attribute header) in + * the class file data + */ + public int getDataSize() { + verifyValid(); + return size - 6; + } + + /** + * @return the number of attributes left in the list, including this + * attribute (if valid) + */ + public int getRemainingAttributesCount() { + return remaining; + } + + /** + * The attribute iterator must be valid. + * + * @return the constant pool index of the name of the attribute + */ + public int getNameIndex() { + verifyValid(); + return cr.getUShort(offset); + } + + /** + * The attribute iterator must be valid. + * + * @return the name of the attribute + */ + public String getName() throws InvalidClassFileException { + verifyValid(); + String s = cr.getUtf8FromAddress(offset); + if (s == null) { + throw new InvalidClassFileException(offset, "Null attribute name"); + } else { + return s; + } + } + + /** + * @return whether this iterator is valid + */ + public boolean isValid() { + return remaining > 0; + } + + /** + * The attribute iterator must be valid. + * + * The iterator is advanced to the next attribute (which might not exist, so + * the iterator might become invalid). + */ + public void advance() { + verifyValid(); + offset += size; + remaining--; + setSize(); + } + } + + /** + * Point iter at the list of attributes for field f. + */ + public void initFieldAttributeIterator(int f, AttrIterator iter) { + verifyFieldIndex(f); + iter.init(this, fieldOffsets[f] + 6); + } + + /** + * @return the offset of the raw class data for field f + */ + public int getFieldRawOffset(int f) { + verifyFieldIndex(f); + return fieldOffsets[f]; + } + + /** + * @return the size of the raw class data for field f + */ + public int getFieldRawSize(int f) { + verifyFieldIndex(f); + return fieldOffsets[f + 1] - fieldOffsets[f]; + } + + /** + * @return the number of methods in the class + */ + public int getMethodCount() { + return methodOffsets.length - 1; + } + + private void verifyMethodIndex(int m) { + if (m < 0 || m >= methodOffsets.length - 1) { + throw new IllegalArgumentException("Invalid method index: " + m); + } + } + + /** + * @return the offset of the raw class data for method m + */ + public int getMethodRawOffset(int m) { + verifyMethodIndex(m); + return methodOffsets[m]; + } + + /** + * @return the size of the raw class data for method m + */ + public int getMethodRawSize(int m) { + verifyMethodIndex(m); + return methodOffsets[m + 1] - methodOffsets[m]; + } + + /** + * @return the access flags for method m + */ + public int getMethodAccessFlags(int m) { + verifyMethodIndex(m); + return getUShort(methodOffsets[m]); + } + + /** + * @return the name of method m + */ + public String getMethodName(int m) throws InvalidClassFileException { + verifyMethodIndex(m); + return getUtf8FromAddress(methodOffsets[m] + 2); + } + + /** + * @return the method descriptor of method m in JVM format (e.g., + * V(ILjava/lang/Object;) ) + */ + public String getMethodType(int m) throws InvalidClassFileException { + verifyMethodIndex(m); + return getUtf8FromAddress(methodOffsets[m] + 4); + } + + /** + * @return the constant pool index of the name of method m + */ + public int getMethodNameIndex(int m) { + verifyMethodIndex(m); + return getUShort(methodOffsets[m] + 2); + } + + /** + * @return the constant pool index of the method descriptor of method m + */ + public int getMethodTypeIndex(int m) { + verifyMethodIndex(m); + return getUShort(methodOffsets[m] + 4); + } + + /** + * Point iter at the list of attributes for method m. + */ + public void initMethodAttributeIterator(int m, AttrIterator iter) { + verifyMethodIndex(m); + iter.init(this, methodOffsets[m] + 6); + } + + /** + * Point iter at the list of attributes for the class. + */ + public void initClassAttributeIterator(AttrIterator iter) { + iter.init(this, attrInfoOffset); + } +} diff --git a/com.ibm.wala.shrike/src/com/ibm/wala/shrikeCT/ClassReaderAttribute.java b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeCT/ClassReaderAttribute.java new file mode 100644 index 000000000..fe8408728 --- /dev/null +++ b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeCT/ClassReaderAttribute.java @@ -0,0 +1,91 @@ +/******************************************************************************* + * 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.shrikeCT; + +/** + * This is a base class for "attribute readers", the classes which provide + * access to the contents of attributes. + */ +public abstract class ClassReaderAttribute { + protected ClassReader cr; + protected int attr; + protected int length; + + /** + * Construct a reader for a particular attribute. + * + * @param attr + * a valid attribute iterator pointing at the attribute to read + * @param expectedName + * the name the attribute must have + */ + protected ClassReaderAttribute(ClassReader.AttrIterator attr, String expectedName) throws InvalidClassFileException { + attr.verifyValid(); + this.cr = attr.cr; + this.attr = attr.offset; + this.length = attr.size; + + String n = attr.getName(); + if (expectedName != n && !expectedName.equals(n)) { + throw new IllegalArgumentException("Attribute " + n + " is not a " + expectedName + " attribute"); + } + } + + /** + * @return the class reader the attribute belongs to + */ + public final ClassReader getClassReader() { + return cr; + } + + /** + * @return the offset of the raw attribute data (including the attribute + * header) + */ + public final int getRawOffset() { + return attr; + } + + /** + * @return the size of the raw attribute data (including the attribute header) + */ + public final int getRawSize() { + return length; + } + + /** + * Ensure that the len bytes starting at offset fall within the attribute + * data. + * + * @throws InvalidClassFileException + * if the bytes fall outside the data + */ + protected final void checkSize(int offset, int len) throws InvalidClassFileException { + if (length < offset - attr + len) { + throw new InvalidClassFileException(offset, "Attribute data too short, expected " + len + " bytes, got " + + (length + attr - offset)); + } + } + + /** + * Ensure that the len bytes starting at offset end at the end of the + * attribute data. + * + * @throws InvalidClassFileException + * if the bytes do not end at the end of the attribute + */ + protected final void checkSizeEquals(int offset, int len) throws InvalidClassFileException { + if (length != offset - attr + len) { + throw new InvalidClassFileException(offset, "Attribute data invalid length, expected " + len + " bytes, got " + + (length + attr - offset)); + } + } +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/src/com/ibm/wala/shrikeCT/ClassWriter.java b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeCT/ClassWriter.java new file mode 100644 index 000000000..254992e53 --- /dev/null +++ b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeCT/ClassWriter.java @@ -0,0 +1,931 @@ +/******************************************************************************* + * 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.shrikeCT; + +import java.util.ArrayList; +import java.util.HashMap; + +/** + * This class formats and writes class data into JVM format. + */ +public final class ClassWriter implements ClassConstants { + // input + private int majorVersion = 46; + private int minorVersion = 0; + private ConstantPoolParser rawCP; + private HashMap cachedCPEntries = new HashMap(1); + private ArrayList newCPEntries = new ArrayList(1); + private int nextCPIndex = 1; + private ArrayList fields = new ArrayList(1); + private ArrayList methods = new ArrayList(1); + private ArrayList classAttributes = new ArrayList(1); + private int thisClass; + private int superClass; + private int[] superInterfaces; + private int accessFlags; + private boolean forceAddCPEntries = false; + + // output + private byte[] buf; + private int bufLen; + + /** + * Create a blank ClassWriter with no methods, fields, or attributes, an empty + * constant pool, no super class, no implemented interfaces, no name, + * majorVersion 46, and minorVersion 0. + */ + public ClassWriter() { + } + + /** + * Set the class file format major version. You probably don't want to use + * this unless you really know what you are doing. + */ + public void setMajorVersion(int major) { + if (major < 0 || major > 0xFFFF) { + throw new IllegalArgumentException("Major version out of range: " + major); + } + majorVersion = major; + } + + /** + * Set the class file format minor version. You probably don't want to use + * this unless you really know what you are doing. + */ + public void setMinorVersion(int minor) { + if (minor < 0 || minor > 0xFFFF) { + throw new IllegalArgumentException("Major version out of range: " + minor); + } + minorVersion = minor; + } + + static abstract class CWItem { + abstract byte getType(); + } + + static class CWString extends CWItem { + private String s; + + CWString(String s) { + this.s = s; + } + + public boolean equals(Object o) { + return o instanceof CWString && ((CWString) o).s.equals(s); + } + + public int hashCode() { + return s.hashCode() + 3901; + } + + byte getType() { + return CONSTANT_String; + } + } + + static class CWClass extends CWItem { + private String c; + + CWClass(String c) { + this.c = c; + } + + public boolean equals(Object o) { + return o instanceof CWClass && ((CWClass) o).c.equals(c); + } + + public int hashCode() { + return c.hashCode() + 1431; + } + + byte getType() { + return CONSTANT_Class; + } + } + + static class CWRef extends CWItem { + private String c; + private String n; + private String t; + private byte type; + + CWRef(byte type, String c, String n, String t) { + this.type = type; + this.c = c; + this.n = n; + this.t = t; + } + + public boolean equals(Object o) { + if (o instanceof CWRef) { + CWRef r = (CWRef) o; + return r.type == type && r.c.equals(c) && r.n.equals(n) && r.t.equals(t); + } else { + return false; + } + } + + public int hashCode() { + return type + (c.hashCode() << 5) + (n.hashCode() << 3) + t.hashCode(); + } + + byte getType() { + return type; + } + } + + static class CWNAT extends CWItem { + private String n; + private String t; + + CWNAT(String n, String t) { + this.n = n; + this.t = t; + } + + public boolean equals(Object o) { + if (o instanceof CWNAT) { + CWNAT r = (CWNAT) o; + return r.n.equals(n) && r.t.equals(t); + } else { + return false; + } + } + + public int hashCode() { + return (n.hashCode() << 3) + t.hashCode(); + } + + byte getType() { + return CONSTANT_NameAndType; + } + } + + /** + * Copy a constant pool from some ClassReader into this class. This must be + * done before any entries are allocated in this ClassWriter's constant pool, + * and it can only be done once. If and only if this is done, it is safe to + * copy "raw" fields, methods and attributes from the ClassReader into this + * class, because the constant pool references in those fields, methods and + * attributes are guaranteed to point to the same constant pool items in this + * new class. + * + * @param cacheEntries + * records whether to parse the raw constant pool completely so that + * if new entries are required which are the same as entries already + * in the raw pool, the existing entries in the raw pool are used + * instead. Setting this to 'true' produces smaller constant pools + * but may slow down performance because the raw pool must be + * completely parsed + */ + public void setRawCP(ConstantPoolParser cp, boolean cacheEntries) throws InvalidClassFileException { + if (rawCP != null) { + throw new IllegalArgumentException("Cannot set raw constant pool twice"); + } + if (nextCPIndex != 1) { + throw new IllegalArgumentException("Cannot set raw constant pool after allocating new entries"); + } + rawCP = cp; + nextCPIndex = cp.getItemCount(); + + if (cacheEntries) { + for (int i = 1; i < nextCPIndex; i++) { + byte t = cp.getItemType(i); + switch (t) { + case CONSTANT_String: + cachedCPEntries.put(new CWString(cp.getCPString(i)), new Integer(i)); + break; + case CONSTANT_Class: + cachedCPEntries.put(new CWClass(cp.getCPClass(i)), new Integer(i)); + break; + case CONSTANT_FieldRef: + case CONSTANT_InterfaceMethodRef: + case CONSTANT_MethodRef: + cachedCPEntries.put(new CWRef(t, cp.getCPRefClass(i), cp.getCPRefName(i), cp.getCPRefType(i)), new Integer(i)); + break; + case CONSTANT_NameAndType: + cachedCPEntries.put(new CWNAT(cp.getCPNATName(i), cp.getCPNATType(i)), new Integer(i)); + break; + case CONSTANT_Integer: + cachedCPEntries.put(new Integer(cp.getCPInt(i)), new Integer(i)); + break; + case CONSTANT_Float: + cachedCPEntries.put(new Float(cp.getCPFloat(i)), new Integer(i)); + break; + case CONSTANT_Long: + cachedCPEntries.put(new Long(cp.getCPLong(i)), new Integer(i)); + break; + case CONSTANT_Double: + cachedCPEntries.put(new Double(cp.getCPDouble(i)), new Integer(i)); + break; + case CONSTANT_Utf8: + cachedCPEntries.put(cp.getCPUtf8(i), new Integer(i)); + break; + } + } + } + } + + /** + * @param force + * true iff you want the addCP methods to always create a new + * constant pool entry and never reuse an existing constant pool + * entry + */ + public void setForceAddCPEntries(boolean force) { + forceAddCPEntries = force; + } + + private int addCPEntry(Object o, int size) { + if (cachedCPEntries == null) { + throw new IllegalArgumentException("Cannot add a new constant pool entry during makeBytes() processing!"); + } + + Integer i = forceAddCPEntries ? null : cachedCPEntries.get(o); + if (i != null) { + return i.intValue(); + } else { + int index = nextCPIndex; + nextCPIndex += size; + i = new Integer(index); + cachedCPEntries.put(o, i); + newCPEntries.add(o); + if (nextCPIndex > 0xFFFF) { + throw new IllegalArgumentException("Constant pool item count exceeded"); + } + return index; + } + } + + /** + * Add a Utf8 string to the constant pool if necessary. + * + * @return the index of a constant pool item with the right value + */ + public int addCPUtf8(String s) { + return addCPEntry(s, 1); + } + + /** + * Add an Integer to the constant pool if necessary. + * + * @return the index of a constant pool item with the right value + */ + public int addCPInt(int i) { + return addCPEntry(new Integer(i), 1); + } + + /** + * Add a Float to the constant pool if necessary. + * + * @return the index of a constant pool item with the right value + */ + public int addCPFloat(float f) { + return addCPEntry(new Float(f), 1); + } + + /** + * Add a Long to the constant pool if necessary. + * + * @return the index of a constant pool item with the right value + */ + public int addCPLong(long l) { + return addCPEntry(new Long(l), 2); + } + + /** + * Add a Double to the constant pool if necessary. + * + * @return the index of a constant pool item with the right value + */ + public int addCPDouble(double d) { + return addCPEntry(new Double(d), 2); + } + + /** + * Add a String to the constant pool if necessary. + * + * @return the index of a constant pool item with the right value + */ + public int addCPString(String s) { + return addCPEntry(new CWString(s), 1); + } + + /** + * Add a Class to the constant pool if necessary. + * + * @param s + * the class name, in JVM format (e.g., java/lang/Object) + * @return the index of a constant pool item with the right value + */ + public int addCPClass(String s) { + return addCPEntry(new CWClass(s), 1); + } + + /** + * Add a FieldRef to the constant pool if necessary. + * + * @param c + * the class name, in JVM format (e.g., java/lang/Object) + * @param n + * the field name + * @param t + * the field type, in JVM format (e.g., I, Z, or Ljava/lang/Object;) + * @return the index of a constant pool item with the right value + */ + public int addCPFieldRef(String c, String n, String t) { + return addCPEntry(new CWRef(CONSTANT_FieldRef, c, n, t), 1); + } + + /** + * Add a MethodRef to the constant pool if necessary. + * + * @param c + * the class name, in JVM format (e.g., java/lang/Object) + * @param n + * the method name + * @param t + * the method type, in JVM format (e.g., V(ILjava/lang/Object;) ) + * @return the index of a constant pool item with the right value + */ + public int addCPMethodRef(String c, String n, String t) { + return addCPEntry(new CWRef(CONSTANT_MethodRef, c, n, t), 1); + } + + /** + * Add an InterfaceMethodRef to the constant pool if necessary. + * + * @param c + * the class name, in JVM format (e.g., java/lang/Object) + * @param n + * the field name + * @param t + * the method type, in JVM format (e.g., V(ILjava/lang/Object;) ) + * @return the index of a constant pool item with the right value + */ + public int addCPInterfaceMethodRef(String c, String n, String t) { + return addCPEntry(new CWRef(CONSTANT_InterfaceMethodRef, c, n, t), 1); + } + + /** + * Add a NameAndType to the constant pool if necessary. + * + * @param n + * the name + * @param t + * the type, in JVM format + * @return the index of a constant pool item with the right value + */ + public int addCPNAT(String n, String t) { + return addCPEntry(new CWNAT(n, t), 1); + } + + /** + * Set the access flags for the class. + */ + public void setAccessFlags(int f) { + if (f < 0 || f > 0xFFFF) { + throw new IllegalArgumentException("Access flags out of range: " + f); + } + accessFlags = f; + } + + /** + * Set the constant pool index for the name of the class. + */ + public void setNameIndex(int c) { + if (c < 1 || c > 0xFFFF) { + throw new IllegalArgumentException("Class name index out of range: " + c); + } + thisClass = c; + } + + /** + * Set the constant pool index for the name of the superclass. + */ + public void setSuperNameIndex(int c) { + if (c < 0 || c > 0xFFFF) { + throw new IllegalArgumentException("Superclass name index out of range: " + c); + } + superClass = c; + } + + /** + * Set the constant pool indices for the names of the implemented interfaces. + */ + public void setInterfaceNameIndices(int[] ifaces) { + if (ifaces != null) { + if (ifaces.length > 0xFFFF) { + throw new IllegalArgumentException("Too many interfaces implemented: " + ifaces.length); + } + for (int i = 0; i < ifaces.length; i++) { + int c = ifaces[i]; + if (c < 1 || c > 0xFFFF) { + throw new IllegalArgumentException("Interface name index out of range: " + c); + } + } + } + superInterfaces = ifaces; + } + + /** + * Set the name of the class. + */ + public void setName(String c) { + setNameIndex(addCPClass(c)); + } + + /** + * Set the name of the superclass; if c is null, then there is no superclass + * (this must be java/lang/Object). + */ + public void setSuperName(String c) { + setSuperNameIndex(c == null ? 0 : addCPClass(c)); + } + + /** + * Set the names of the implemented interfaces. + */ + public void setInterfaceNames(String[] ifaces) { + if (ifaces == null) { + setInterfaceNameIndices((int[]) null); + } else { + int[] ifs = new int[ifaces.length]; + for (int i = 0; i < ifaces.length; i++) { + ifs[i] = addCPClass(ifaces[i]); + } + setInterfaceNameIndices(ifs); + } + } + + /** + * An Element is an object that can be serialized into a byte buffer. + * Serialization via 'copyInto' is performed when the user calls makeBytes() + * on the ClassWriter. At this time no new constant pool items can be + * allocated, so any item indices that need to be emitted must be allocated + * earlier. + */ + public static abstract class Element { + public Element() { + } + + /** + * @return the number of bytes that will be generated. + */ + public abstract int getSize(); + + /** + * Copy the bytes into 'buf' at offset 'offset'. + * + * @return the number of bytes copies, which must be equal to getSize() + */ + public abstract int copyInto(byte[] buf, int offset); + } + + /** + * A RawElement is an Element that is already available as some chunk of a + * byte buffer. + */ + public static final class RawElement extends Element { + private byte[] buf; + private int offset; + private int len; + + /** + * Create an Element for the 'len' bytes in 'buf' at offset 'offset'. + */ + public RawElement(byte[] buf, int offset, int len) { + this.buf = buf; + this.offset = offset; + this.len = len; + } + + public int getSize() { + return len; + } + + public int copyInto(byte[] dest, int destOffset) { + System.arraycopy(buf, offset, dest, destOffset, len); + return destOffset + len; + } + } + + /** + * Add a method to the class, the method data given as "raw" bytes (probably + * obtained from a ClassReader). + */ + public void addRawMethod(Element e) { + methods.add(e); + } + + /** + * Add a field to the class, the field data given as "raw" bytes (probably + * obtained from a ClassReader). + */ + public void addRawField(Element e) { + fields.add(e); + } + + /** + * Add a method to the class. + * + * @param access + * the access flags + * @param name + * the method name + * @param type + * the method type in JVM format (e.g., V(ILjava/lang/Object;) ) + * @param attributes + * the attributes in raw form, one Element per attribute + */ + public void addMethod(int access, String name, String type, Element[] attributes) { + addMethod(access, addCPUtf8(name), addCPUtf8(type), attributes); + } + + /** + * Add a field to the class. + * + * @param access + * the access flags + * @param name + * the field name + * @param type + * the field type in JVM format (e.g., I, Z, Ljava/lang/Object;) + * @param attributes + * the attributes in raw form, one Element per attribute + */ + public void addField(int access, String name, String type, Element[] attributes) { + addField(access, addCPUtf8(name), addCPUtf8(type), attributes); + } + + static final class MemberElement extends Element { + private int access; + private int name; + private int type; + private Element[] attributes; + + public MemberElement(int access, int name, int type, Element[] attributes) { + if (access < 0 || access > 0xFFFF) { + throw new IllegalArgumentException("Access flags out of range: " + access); + } + if (name < 1 || name > 0xFFFF) { + throw new IllegalArgumentException("Name constant pool index out of range: " + name); + } + if (type < 1 || type > 0xFFFF) { + throw new IllegalArgumentException("Type constant pool index out of range: " + name); + } + if (attributes.length > 0xFFFF) { + throw new IllegalArgumentException("Too many attributes: " + attributes.length); + } + + this.access = access; + this.name = name; + this.type = type; + this.attributes = attributes; + } + + public int getSize() { + int size = 8; + if (attributes != null) { + for (int i = 0; i < attributes.length; i++) { + size += attributes[i].getSize(); + } + } + return size; + } + + public int copyInto(byte[] buf, int offset) { + setUShort(buf, offset, access); + setUShort(buf, offset + 2, name); + setUShort(buf, offset + 4, type); + if (attributes != null) { + setUShort(buf, offset + 6, attributes.length); + offset += 8; + for (int i = 0; i < attributes.length; i++) { + offset = attributes[i].copyInto(buf, offset); + } + } else { + setUShort(buf, offset + 6, 0); + offset += 8; + } + return offset; + } + } + + /** + * Add a method to the class. + * + * @param access + * the access flags + * @param name + * the constant pool index of the method name + * @param type + * the constant pool index of the method type in JVM format (e.g., + * V(ILjava/lang/Object;) ) + * @param attributes + * the attributes in raw form, one Element per attribute + */ + public void addMethod(int access, int name, int type, Element[] attributes) { + //int idx=methods.size()-2; + //if (idx<0) idx=0; + //methods.add(0,new MemberElement(access, name, type, attributes)); + methods.add(new MemberElement(access, name, type, attributes)); + if (methods.size() > 0xFFFF) { + throw new IllegalArgumentException("Too many methods"); + } + } + + /** + * Add a field to the class. + * + * @param access + * the access flags + * @param name + * the constant pool index of the field name + * @param type + * the constant pool index of the field type in JVM format (e.g., I, + * Z, Ljava/lang/Object;) + * @param attributes + * the attributes in raw form, one Element per attribute + */ + public void addField(int access, int name, int type, Element[] attributes) { + fields.add(new MemberElement(access, name, type, attributes)); + if (fields.size() > 0xFFFF) { + throw new IllegalArgumentException("Too many fields"); + } + } + + /** + * Add an atttribute to the class. + * + * @param attribute + * the attribute in raw form + */ + public void addClassAttribute(Element attribute) { + classAttributes.add(attribute); + if (classAttributes.size() > 0xFFFF) { + throw new IllegalArgumentException("Too many class attributes: " + classAttributes.size()); + } + } + + private int reserveBuf(int size) { + if (buf == null) { + buf = new byte[size]; + } else if (bufLen + size > buf.length) { + byte[] newBuf = new byte[Math.max(buf.length * 2, bufLen + size)]; + System.arraycopy(buf, 0, newBuf, 0, bufLen); + buf = newBuf; + } + int offset = bufLen; + bufLen += size; + return offset; + } + + private void emitElement(Element e) { + int size = e.getSize(); + int offset = reserveBuf(size); + int finalOffset = e.copyInto(buf, offset); + if (finalOffset - offset != size) { + throw new Error("Element failed to output the promised bytes: promised " + size + ", got " + (finalOffset - offset)); + } + } + + private static final char[] noChars = new char[0]; + + private void emitConstantPool() { + if (rawCP != null) { + int len = rawCP.getRawSize(); + int offset = reserveBuf(len); + System.arraycopy(rawCP.getRawBytes(), rawCP.getRawOffset(), buf, offset, len); + } + + char[] chars = noChars; + + // BE CAREFUL: the newCPEntries array grows during this loop. + for (int i = 0; i < newCPEntries.size(); i++) { + Object o = newCPEntries.get(i); + if (o instanceof CWItem) { + CWItem item = (CWItem) o; + byte t = item.getType(); + int offset; + switch (t) { + case CONSTANT_Class: + offset = reserveBuf(3); + setUShort(buf, offset + 1, addCPUtf8(((CWClass) item).c)); + break; + case CONSTANT_String: + offset = reserveBuf(3); + setUShort(buf, offset + 1, addCPUtf8(((CWString) item).s)); + break; + case CONSTANT_NameAndType: { + offset = reserveBuf(5); + CWNAT nat = (CWNAT) item; + setUShort(buf, offset + 1, addCPUtf8(nat.n)); + setUShort(buf, offset + 3, addCPUtf8(nat.t)); + break; + } + case CONSTANT_MethodRef: + case CONSTANT_FieldRef: + case CONSTANT_InterfaceMethodRef: { + offset = reserveBuf(5); + CWRef ref = (CWRef) item; + setUShort(buf, offset + 1, addCPClass(ref.c)); + setUShort(buf, offset + 3, addCPNAT(ref.n, ref.t)); + break; + } + default: + throw new Error("Invalid type: " + t); + } + buf[offset] = t; + } else { + if (o instanceof String) { + String s = (String) o; + int slen = s.length(); + + if (chars.length < slen) { + chars = new char[slen]; + } + s.getChars(0, slen, chars, 0); + + int offset = reserveBuf(3); + buf[offset] = CONSTANT_Utf8; + + int maxBytes = slen * 3; + int p = reserveBuf(maxBytes); // worst case reservation + + for (int j = 0; j < slen; j++) { + char ch = chars[j]; + if (ch == 0) { + setUShort(buf, p, 0xC080); + p += 2; + } else if (ch < 0x80) { + buf[p] = (byte) ch; + p += 1; + } else if (ch < 0x800) { + buf[p] = (byte) ((ch >> 6) | 0xC0); + buf[p + 1] = (byte) ((ch & 0x3F) | 0x80); + p += 2; + } else { + buf[p] = (byte) ((ch >> 12) | 0xE0); + buf[p + 1] = (byte) (((ch >> 6) & 0x3F) | 0x80); + buf[p + 2] = (byte) ((ch & 0x3F) | 0x80); + p += 3; + } + } + int bytes = p - (offset + 3); + reserveBuf(bytes - maxBytes); // negative reservation to push back buf + // size + if (bytes > 0xFFFF) { + throw new IllegalArgumentException("String too long: " + bytes + " bytes"); + } + setUShort(buf, offset + 1, bytes); + } else if (o instanceof Integer) { + int offset = reserveBuf(5); + buf[offset] = CONSTANT_Integer; + setInt(buf, offset + 1, ((Integer) o).intValue()); + } else if (o instanceof Long) { + int offset = reserveBuf(9); + buf[offset] = CONSTANT_Long; + setLong(buf, offset + 1, ((Long) o).longValue()); + } else if (o instanceof Float) { + int offset = reserveBuf(5); + buf[offset] = CONSTANT_Float; + setFloat(buf, offset + 1, ((Float) o).intValue()); + } else if (o instanceof Double) { + int offset = reserveBuf(9); + buf[offset] = CONSTANT_Double; + setDouble(buf, offset + 1, ((Double) o).intValue()); + } + } + } + } + + /** + * After you've added everything you need to the class, call this method to + * generate the actual class file data. This can only be called once. + */ + public byte[] makeBytes() { + if (buf != null) { + throw new IllegalArgumentException("Can't call makeBytes() twice"); + } + + if (thisClass == 0) { + throw new IllegalArgumentException("No class name set"); + } + + reserveBuf(10); + setInt(buf, 0, MAGIC); + setUShort(buf, 4, minorVersion); + setUShort(buf, 6, majorVersion); + + emitConstantPool(); + // The constant pool can grow during emmission, so store the size last + setUShort(buf, 8, nextCPIndex); + // No new constant pool entries can be allocated; make sure we + // catch any such error by client code + cachedCPEntries = null; + + int offset = reserveBuf(8); + setUShort(buf, offset, accessFlags); + setUShort(buf, offset + 2, thisClass); + setUShort(buf, offset + 4, superClass); + if (superInterfaces != null) { + setUShort(buf, offset + 6, superInterfaces.length); + reserveBuf(superInterfaces.length * 2); + for (int i = 0; i < superInterfaces.length; i++) { + setUShort(buf, offset + 8 + i * 2, superInterfaces[i]); + } + } else { + setUShort(buf, offset + 6, 0); + } + + offset = reserveBuf(2); + int numFields = fields.size(); + setUShort(buf, offset, numFields); + for (int i = 0; i < numFields; i++) { + emitElement(fields.get(i)); + } + + offset = reserveBuf(2); + int numMethods = methods.size(); + //Xiangyu, debug + //System.out.println("numMethods="+numMethods); + setUShort(buf, offset, numMethods); + for (int i = 0; i < numMethods; i++) { + emitElement(methods.get(i)); + } + + offset = reserveBuf(2); + int numAttrs = classAttributes.size(); + setUShort(buf, offset, numAttrs); + for (int i = 0; i < numAttrs; i++) { + emitElement(classAttributes.get(i)); + } + + if (buf.length == bufLen) { + return buf; + } else { + byte[] b = new byte[bufLen]; + System.arraycopy(buf, 0, b, 0, bufLen); + return b; + } + } + + /** + * Set the byte at offset 'offset' in 'buf' to the unsigned 8-bit value in v. + */ + public static void setUByte(byte[] buf, int offset, int v) { + buf[offset] = (byte) v; + } + + /** + * Set the 4 bytes at offset 'offset' in 'buf' to the signed 32-bit value in + * v. + */ + public static void setInt(byte[] buf, int offset, int v) { + buf[offset] = (byte) (v >> 24); + buf[offset + 1] = (byte) (v >> 16); + buf[offset + 2] = (byte) (v >> 8); + buf[offset + 3] = (byte) v; + } + + /** + * Set the 8 bytes at offset 'offset' in 'buf' to the signed 64-bit value in + * v. + */ + public static void setLong(byte[] buf, int offset, long v) { + setInt(buf, offset, (int) (v >> 32)); + setInt(buf, offset + 4, (int) v); + } + + /** + * Set the 4 bytes at offset 'offset' in 'buf' to the float value in v. + */ + public static void setFloat(byte[] buf, int offset, float v) { + setInt(buf, offset, Float.floatToIntBits(v)); + } + + /** + * Set the 8 bytes at offset 'offset' in 'buf' to the double value in v. + */ + public static void setDouble(byte[] buf, int offset, double v) { + setLong(buf, offset, Double.doubleToRawLongBits(v)); + } + + /** + * Set the 2 bytes at offset 'offset' in 'buf' to the unsigned 16-bit value in + * v. + */ + public static void setUShort(byte[] buf, int offset, int v) { + buf[offset] = (byte) (v >> 8); + buf[offset + 1] = (byte) v; + } +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/src/com/ibm/wala/shrikeCT/CodeReader.java b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeCT/CodeReader.java new file mode 100644 index 000000000..b9f927ff9 --- /dev/null +++ b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeCT/CodeReader.java @@ -0,0 +1,95 @@ +/******************************************************************************* + * 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.shrikeCT; + +/** + * This attribute reader reads Code attributes from methods. + */ +public final class CodeReader extends ClassReaderAttribute { + private int codeLen; + private int exnTableLen; + + public CodeReader(ClassReader.AttrIterator iter) throws InvalidClassFileException { + super(iter, "Code"); + + int offset = attr + 6; + checkSize(offset, 8); + codeLen = cr.getInt(offset + 4); + offset += 8; + + checkSize(offset, codeLen + 2); + offset += codeLen; + exnTableLen = cr.getUShort(offset); + offset += 2; + checkSize(offset, exnTableLen * 8 + 2); + offset += exnTableLen * 8; + int attrCount = cr.getUShort(offset); + offset += 2; + for (int i = 0; i < attrCount; i++) { + checkSize(offset, 6); + int len = cr.getInt(offset + 2); + offset += 6; + checkSize(offset, len); + offset += len; + } + } + + /** + * @return the maximum stack size used by the code, in words + */ + public int getMaxStack() { + return cr.getUShort(attr + 6); + } + + /** + * @return the maximum local variable size used by the code, in words + */ + public int getMaxLocals() { + return cr.getUShort(attr + 8); + } + + /** + * @return the length of the bytecode array, in bytes + */ + public int getBytecodeLength() { + return codeLen; + } + + /** + * @return the bytecode bytes + */ + public byte[] getBytecode() { + byte[] r = new byte[codeLen]; + System.arraycopy(cr.getBytes(), attr + 14, r, 0, r.length); + return r; + } + + /** + * @return the raw exception handler data, a flattened sequence of (startPC, + * endPC, catchClassIndex, catchPC) tuples + */ + public int[] getRawHandlers() { + int[] r = new int[exnTableLen * 4]; + int offset = attr + 14 + codeLen + 2; + for (int i = 0; i < r.length; i++) { + r[i] = cr.getUShort(offset); + offset += 2; + } + return r; + } + + /** + * Point iter at the list of attributes for this code. + */ + public void initAttributeIterator(ClassReader.AttrIterator iter) { + iter.init(cr, attr + 14 + codeLen + 2 + exnTableLen * 8); + } +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/src/com/ibm/wala/shrikeCT/CodeWriter.java b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeCT/CodeWriter.java new file mode 100644 index 000000000..c9c3b07e0 --- /dev/null +++ b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeCT/CodeWriter.java @@ -0,0 +1,153 @@ +/******************************************************************************* + * 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.shrikeCT; + +/** + * This class helps emit Code elements. + * + * After constructing a CodeWriter, at least the max stack, max locals and + * bytecode bytes must be set before it can be used. + */ +public final class CodeWriter extends ClassWriter.Element { + private int attrID; + private int maxLocals = -1; + private int maxStack = -1; + private byte[] code; + private int[] exnHandlers; + private ClassWriter.Element[] attributes; + + /** + * Build an empty serializable Code attribute. + */ + public CodeWriter(ClassWriter w) { + attrID = w.addCPUtf8("Code"); + } + + private void verify() { + if (maxStack < 0) { + throw new IllegalArgumentException("maxStack not set"); + } + if (maxLocals < 0) { + throw new IllegalArgumentException("maxLocals not set"); + } + if (code == null) { + throw new IllegalArgumentException("No bytecodes set"); + } + } + + //By Xiangyu + public int getCodeLength() { + return code.length; + } + + public int getSize() { + verify(); + + int size = 14 + code.length + 2 + (exnHandlers == null ? 0 : exnHandlers.length) * 2 + 2; + if (attributes != null) { + for (int i = 0; i < attributes.length; i++) { + size += attributes[i].getSize(); + } + } + return size; + } + + public int copyInto(byte[] buf, int offset) { + verify(); + + int start = offset; + ClassWriter.setUShort(buf, offset, attrID); + ClassWriter.setUShort(buf, offset + 6, maxStack); + ClassWriter.setUShort(buf, offset + 8, maxLocals); + ClassWriter.setInt(buf, offset + 10, code.length); + offset += 14; + System.arraycopy(code, 0, buf, offset, code.length); + offset += code.length; + ClassWriter.setUShort(buf, offset, (exnHandlers == null ? 0 : exnHandlers.length) / 4); + offset += 2; + if (exnHandlers != null) { + for (int i = 0; i < exnHandlers.length; i++) { + ClassWriter.setUShort(buf, offset, exnHandlers[i]); + offset += 2; + } + } + + ClassWriter.setUShort(buf, offset, (attributes == null ? 0 : attributes.length)); + offset += 2; + if (attributes != null) { + for (int i = 0; i < attributes.length; i++) { + offset = attributes[i].copyInto(buf, offset); + } + } + ClassWriter.setInt(buf, start + 2, offset - start - 6); + return offset; + } + + /** + * Set the bytecodes for this Code attribute. + */ + public void setCode(byte[] code) { + if (code.length > 0xFFFF) { + throw new IllegalArgumentException("Code array is too long: " + code.length); + } + if (code.length == 0) { + throw new IllegalArgumentException("Code array is empty"); + } + + this.code = code; + } + + /** + * Set the raw handler data for this Code attribute. + * + * @param exnHandlers + * a flattened sequence of (startPC, endPC, catchClassIndex, catchPC) + * tuples + */ + public void setRawHandlers(int[] exnHandlers) { + if (exnHandlers.length % 4 != 0) { + throw new IllegalArgumentException("Exception handlers array has bad length: " + exnHandlers.length); + } + if (exnHandlers.length / 4 > 0xFFFF) { + throw new IllegalArgumentException("Too many exception handlers: " + exnHandlers.length / 4); + } + for (int i = 0; i < exnHandlers.length; i++) { + int v = exnHandlers[i]; + if (v < 0 || v > 0xFFFF) { + throw new IllegalArgumentException("Invalid exception handler entry at " + i); + } + } + + this.exnHandlers = exnHandlers; + } + + /** + * Set the maximum number of local variable space used, in words, by this + * Code. + */ + public void setMaxLocals(int maxLocals) { + this.maxLocals = maxLocals; + } + + /** + * Set the maximum stack size, in words, in this Code. + */ + public void setMaxStack(int maxStack) { + this.maxStack = maxStack; + } + + /** + * Set the attributes of this Code. + */ + public void setAttributes(ClassWriter.Element[] attributes) { + this.attributes = attributes; + } +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/src/com/ibm/wala/shrikeCT/ConstantPoolParser.java b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeCT/ConstantPoolParser.java new file mode 100644 index 000000000..f6845454a --- /dev/null +++ b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeCT/ConstantPoolParser.java @@ -0,0 +1,420 @@ +/******************************************************************************* + * 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.shrikeCT; + +/** + * A ConstantPoolParser provides read-only access to the constant pool of a + * class file. + */ +public final class ConstantPoolParser implements ClassConstants { + private byte[] bytes; + private int[] cpOffsets; + private String[] cpItems; + + /** + * @param bytes + * the raw class file data + * @param offset + * the start of the constant pool data + * @param itemCount + * the number of items in the pool + */ + public ConstantPoolParser(byte[] bytes, int offset, int itemCount) throws InvalidClassFileException { + this.bytes = bytes; + parseConstantPool(offset, itemCount); + } + + /** + * @return the buffer holding the raw class file data + */ + public byte[] getRawBytes() { + return bytes; + } + + /** + * @return the offset of the constant pool data in the raw class file buffer + */ + public int getRawOffset() { + return cpOffsets[1]; + } + + /** + * @return the size of the constant pool data in the raw class file buffer + */ + public int getRawSize() { + return cpOffsets[cpOffsets.length - 1] - cpOffsets[1]; + } + + /** + * @return the number of constant pool items (maximum item index plus one) + */ + public int getItemCount() { + return cpOffsets.length - 1; + } + + private void checkLength(int offset, int required) throws InvalidClassFileException { + if (bytes.length < offset + required) { + throw new InvalidClassFileException(offset, "file truncated, expected " + required + " bytes, saw only " + + (bytes.length - offset)); + } + } + + /** + * @return the type of constant pool item i, or 0 if i is an unused constant + * pool item + */ + public byte getItemType(int i) { + if (i < 1 || i >= cpItems.length) { + throw new IllegalArgumentException("Constant pool item #" + i + " out of range"); + } + int offset = cpOffsets[i]; + if (offset == 0) { + return 0; + } else { + return getByte(offset); + } + } + + /** + * @return the name of the Class at constant pool item i, in JVM format (e.g., + * java/lang/Object) + */ + public String getCPClass(int i) throws InvalidClassFileException { + if (i < 1 || i >= cpItems.length) { + throw new IllegalArgumentException("Constant pool item #" + i + " out of range"); + } + int offset = cpOffsets[i]; + if (offset == 0 || getByte(offset) != CONSTANT_Class) { + throw new IllegalArgumentException("Constant pool item #" + i + " is not a Class"); + } + String s = cpItems[i]; + if (s == null) { + try { + s = getCPUtf8(getUShort(offset + 1)); + } catch (IllegalArgumentException ex) { + throw new InvalidClassFileException(offset, "Invalid class name at constant pool item #" + i + ": " + ex.getMessage()); + } + cpItems[i] = s; + } + return s; + } + + /** + * @return the String at constant pool item i + */ + public String getCPString(int i) throws InvalidClassFileException { + if (i < 1 || i >= cpItems.length) { + throw new IllegalArgumentException("Constant pool item #" + i + " out of range"); + } + int offset = cpOffsets[i]; + if (offset == 0 || getByte(offset) != CONSTANT_String) { + throw new IllegalArgumentException("Constant pool item #" + i + " is not a String"); + } + String s = cpItems[i]; + if (s == null) { + try { + s = getCPUtf8(getUShort(offset + 1)); + } catch (IllegalArgumentException ex) { + throw new InvalidClassFileException(offset, "Invalid string at constant pool item #" + i + ": " + ex.getMessage()); + } + cpItems[i] = s; + } + return s; + } + + private static boolean isRef(byte b) { + switch (b) { + case CONSTANT_MethodRef: + case CONSTANT_FieldRef: + case CONSTANT_InterfaceMethodRef: + return true; + default: + return false; + } + } + + /** + * @return the name of the class part of the FieldRef, MethodRef, or + * InterfaceMethodRef at constant pool item i + */ + public String getCPRefClass(int i) throws InvalidClassFileException { + if (i < 1 || i >= cpItems.length) { + throw new IllegalArgumentException("Constant pool item #" + i + " out of range"); + } + int offset = cpOffsets[i]; + if (offset == 0 || !isRef(getByte(offset))) { + throw new IllegalArgumentException("Constant pool item #" + i + " is not a Ref"); + } + try { + return getCPClass(getUShort(offset + 1)); + } catch (IllegalArgumentException ex) { + throw new InvalidClassFileException(offset, "Invalid Ref class at constant pool item #" + i + ": " + ex.getMessage()); + } + } + + /** + * @return the name part of the FieldRef, MethodRef, or InterfaceMethodRef at + * constant pool item i + */ + public String getCPRefName(int i) throws InvalidClassFileException { + if (i < 1 || i >= cpItems.length) { + throw new IllegalArgumentException("Constant pool item #" + i + " out of range"); + } + int offset = cpOffsets[i]; + if (offset == 0 || !isRef(getByte(offset))) { + throw new IllegalArgumentException("Constant pool item #" + i + " is not a Ref"); + } + try { + return getCPNATName(getUShort(offset + 3)); + } catch (IllegalArgumentException ex) { + throw new InvalidClassFileException(offset, "Invalid Ref NameAndType at constant pool item #" + i + ": " + ex.getMessage()); + } + } + + /** + * @return the type part of the FieldRef, MethodRef, or InterfaceMethodRef at + * constant pool item i, in JVM format (e.g., I, Z, or + * Ljava/lang/Object;) + */ + public String getCPRefType(int i) throws InvalidClassFileException { + if (i < 1 || i >= cpItems.length) { + throw new IllegalArgumentException("Constant pool item #" + i + " out of range"); + } + int offset = cpOffsets[i]; + if (offset == 0 || !isRef(getByte(offset))) { + throw new IllegalArgumentException("Constant pool item #" + i + " is not a Ref"); + } + try { + return getCPNATType(getUShort(offset + 3)); + } catch (IllegalArgumentException ex) { + throw new InvalidClassFileException(offset, "Invalid Ref NameAndType at constant pool item #" + i + ": " + ex.getMessage()); + } + } + + /** + * @return the name part of the NameAndType at constant pool item i + */ + public String getCPNATName(int i) throws InvalidClassFileException { + if (i < 1 || i >= cpItems.length) { + throw new IllegalArgumentException("Constant pool item #" + i + " out of range"); + } + int offset = cpOffsets[i]; + if (offset == 0 || getByte(offset) != CONSTANT_NameAndType) { + throw new IllegalArgumentException("Constant pool item #" + i + " is not a NameAndType"); + } + try { + return getCPUtf8(getUShort(offset + 1)); + } catch (IllegalArgumentException ex) { + throw new InvalidClassFileException(offset, "Invalid NameAndType name at constant pool item #" + i + ": " + ex.getMessage()); + } + } + + /** + * @return the type part of the NameAndType at constant pool item i, in JVM + * format (e.g., I, Z, or Ljava/lang/Object;) + */ + public String getCPNATType(int i) throws InvalidClassFileException { + if (i < 1 || i >= cpItems.length) { + throw new IllegalArgumentException("Constant pool item #" + i + " out of range"); + } + int offset = cpOffsets[i]; + if (offset == 0 || getByte(offset) != CONSTANT_NameAndType) { + throw new IllegalArgumentException("Constant pool item #" + i + " is not a NameAndType"); + } + try { + return getCPUtf8(getUShort(offset + 3)); + } catch (IllegalArgumentException ex) { + throw new InvalidClassFileException(offset, "Invalid NameAndType type at constant pool item #" + i + ": " + ex.getMessage()); + } + } + + /** + * @return the value of the Integer at constant pool item i + */ + public int getCPInt(int i) throws InvalidClassFileException { + if (i < 1 || i >= cpItems.length) { + throw new IllegalArgumentException("Constant pool item #" + i + " out of range"); + } + int offset = cpOffsets[i]; + if (offset == 0 || getByte(offset) != CONSTANT_Integer) { + throw new IllegalArgumentException("Constant pool item #" + i + " is not an Integer"); + } + return getInt(offset + 1); + } + + /** + * @return the value of the Float at constant pool item i + */ + public float getCPFloat(int i) throws InvalidClassFileException { + if (i < 1 || i >= cpItems.length) { + throw new IllegalArgumentException("Constant pool item #" + i + " out of range"); + } + int offset = cpOffsets[i]; + if (offset == 0 || getByte(offset) != CONSTANT_Float) { + throw new IllegalArgumentException("Constant pool item #" + i + " is not a Float"); + } + return getFloat(offset + 1); + } + + /** + * @return the value of the Long at constant pool item i + */ + public long getCPLong(int i) throws InvalidClassFileException { + if (i < 1 || i >= cpItems.length) { + throw new IllegalArgumentException("Constant pool item #" + i + " out of range"); + } + int offset = cpOffsets[i]; + if (offset == 0 || getByte(offset) != CONSTANT_Long) { + throw new IllegalArgumentException("Constant pool item #" + i + " is not a Long"); + } + return getLong(offset + 1); + } + + /** + * @return the value of the Double at constant pool item i + */ + public double getCPDouble(int i) throws InvalidClassFileException { + if (i < 1 || i >= cpItems.length) { + throw new IllegalArgumentException("Constant pool item #" + i + " out of range"); + } + int offset = cpOffsets[i]; + if (offset == 0 || getByte(offset) != CONSTANT_Double) { + throw new IllegalArgumentException("Constant pool item #" + i + " is not a Double"); + } + return getDouble(offset + 1); + } + + private InvalidClassFileException invalidUtf8(int item, int offset) { + return new InvalidClassFileException(offset, "Constant pool item #" + item + " starting at " + cpOffsets[item] + + ", is an invalid Java Utf8 string (byte is " + getByte(offset) + ")"); + } + + /** + * @return the value of the Utf8 string at constant pool item i + */ + public String getCPUtf8(int i) throws InvalidClassFileException { + if (i < 1 || i >= cpItems.length) { + throw new IllegalArgumentException("Constant pool item #" + i + " out of range"); + } + int offset = cpOffsets[i]; + if (offset == 0 || getByte(offset) != CONSTANT_Utf8) { + throw new IllegalArgumentException("Constant pool item #" + i + " is not a Utf8"); + } + String s = cpItems[i]; + if (s == null) { + int count = getUShort(offset + 1); + int end = count + offset + 3; + StringBuffer buf = new StringBuffer(count); + offset += 3; + while (offset < end) { + byte x = getByte(offset); + if ((x & 0x80) == 0) { + if (x == 0) { + throw invalidUtf8(i, offset); + } + buf.append((char) x); + offset++; + } else if ((x & 0xE0) == 0xC0) { + if (offset + 1 >= end) { + throw invalidUtf8(i, offset); + } + byte y = getByte(offset + 1); + if ((y & 0xC0) != 0x80) { + throw invalidUtf8(i, offset); + } + buf.append((char) (((x & 0x1F) << 6) + (y & 0x3F))); + offset += 2; + } else if ((x & 0xF0) == 0xE0) { + if (offset + 2 >= end) { + throw invalidUtf8(i, offset); + } + byte y = getByte(offset + 1); + byte z = getByte(offset + 2); + if ((y & 0xC0) != 0x80 || (z & 0xC0) != 0x80) { + throw invalidUtf8(i, offset); + } + buf.append((char) (((x & 0x0F) << 12) + ((y & 0x3F) << 6) + (z & 0x3F))); + offset += 3; + } else { + throw invalidUtf8(i, offset); + } + } + s = buf.toString().intern(); + cpItems[i] = s; + } + return s; + } + + private void parseConstantPool(int offset, int itemCount) throws InvalidClassFileException { + cpOffsets = new int[itemCount + 1]; + cpItems = new String[itemCount]; + for (int i = 1; i < itemCount; i++) { + cpOffsets[i] = offset; + byte tag = getByte(offset); + int itemLen; + switch (tag) { + case CONSTANT_String: + case CONSTANT_Class: + itemLen = 2; + break; + case CONSTANT_NameAndType: + case CONSTANT_MethodRef: + case CONSTANT_FieldRef: + case CONSTANT_InterfaceMethodRef: + case CONSTANT_Integer: + case CONSTANT_Float: + itemLen = 4; + break; + case CONSTANT_Long: + case CONSTANT_Double: + itemLen = 8; + i++; // ick + break; + case CONSTANT_Utf8: + itemLen = 2 + getUShort(offset + 1); + break; + default: + throw new InvalidClassFileException(offset, "unknown constant pool entry type" + tag); + } + checkLength(offset, itemLen); + offset += itemLen + 1; + } + cpOffsets[itemCount] = offset; + } + + private byte getByte(int i) { + return bytes[i]; + } + + private int getUShort(int i) { + return ((bytes[i] & 0xFF) << 8) + (bytes[i + 1] & 0xFF); + } + +// private short getShort(int i) { +// return (short) ((bytes[i] << 8) + (bytes[i + 1] & 0xFF)); +// } + + private int getInt(int i) { + return (bytes[i] << 24) + ((bytes[i + 1] & 0xFF) << 16) + ((bytes[i + 2] & 0xFF) << 8) + (bytes[i + 3] & 0xFF); + } + + private long getLong(int i) { + return ((long) getInt(i) << 32) + ((long) getInt(i + 4) & 0xFFFFFFFFL); + } + + private float getFloat(int i) { + return Float.intBitsToFloat(getInt(i)); + } + + private double getDouble(int i) { + return Double.longBitsToDouble(getLong(i)); + } +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/src/com/ibm/wala/shrikeCT/ConstantValueReader.java b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeCT/ConstantValueReader.java new file mode 100644 index 000000000..d565a4f08 --- /dev/null +++ b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeCT/ConstantValueReader.java @@ -0,0 +1,32 @@ +/******************************************************************************* + * 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.shrikeCT; + +/** + * This class reads ConstantValue attributes. + */ +public final class ConstantValueReader extends ClassReaderAttribute { + /** + * Build a reader for the attribute 'iter'. + */ + public ConstantValueReader(ClassReader.AttrIterator iter) throws InvalidClassFileException { + super(iter, "ConstantValue"); + + checkSizeEquals(attr + 6, 2); + } + + /** + * @return the index of the constant pool item holding the value + */ + public int getValueCPIndex() { + return cr.getUShort(attr + 6); + } +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/src/com/ibm/wala/shrikeCT/ConstantValueWriter.java b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeCT/ConstantValueWriter.java new file mode 100644 index 000000000..aa518267e --- /dev/null +++ b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeCT/ConstantValueWriter.java @@ -0,0 +1,136 @@ +/******************************************************************************* + * 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.shrikeCT; + +/** + * This class builds serializable ConstantValue attributes. These attributes are + * associated with final fields. + * + * After constructing a ConstantValueWriter, you must call setValueCPIndex. + */ +public final class ConstantValueWriter extends ClassWriter.Element { + private int attrID; + private int index = -1; + private ClassWriter w; + + /** + * Build an empty writer. + */ + public ConstantValueWriter(ClassWriter w) { + this.w = w; + attrID = w.addCPUtf8("ConstantValue"); + } + + /** + * Build an writer for a 'long' constant value. + */ + public ConstantValueWriter(ClassWriter w, long v) { + this(w); + setLong(v); + } + + /** + * Build an writer for an 'int' constant value. + */ + public ConstantValueWriter(ClassWriter w, int v) { + this(w); + setInt(v); + } + + /** + * Build an writer for a 'float' constant value. + */ + public ConstantValueWriter(ClassWriter w, float v) { + this(w); + setFloat(v); + } + + /** + * Build an writer for a 'double' constant value. + */ + public ConstantValueWriter(ClassWriter w, double v) { + this(w); + setDouble(v); + } + + /** + * Build an writer for a 'String' constant value. + */ + public ConstantValueWriter(ClassWriter w, String v) { + this(w); + setString(v); + } + + private void verify() { + if (index < 0) { + throw new IllegalArgumentException("The value's constant pool index is not set"); + } + } + + public int getSize() { + verify(); + return 8; + } + + public int copyInto(byte[] buf, int offset) { + verify(); + ClassWriter.setUShort(buf, offset, attrID); + ClassWriter.setInt(buf, offset + 2, 2); + ClassWriter.setUShort(buf, offset + 6, index); + return offset + 8; + } + + /** + * Set the constant value to a long. + */ + public void setLong(long value) { + this.index = w.addCPLong(value); + } + + /** + * Set the constant value to a double. + */ + public void setDouble(double value) { + this.index = w.addCPDouble(value); + } + + /** + * Set the constant value to an int. + */ + public void setInt(int value) { + this.index = w.addCPInt(value); + } + + /** + * Set the constant value to a float. + */ + public void setFloat(float value) { + this.index = w.addCPFloat(value); + } + + /** + * Set the constant value to a String. + */ + public void setString(String value) { + this.index = w.addCPString(value); + } + + /** + * Set the index of the constant pool item holding the constant value. + */ + public void setValueCPIndex(int index) { + if (index < 1 || index > 0xFFFF) { + throw new IllegalArgumentException("Invalid CP index: " + index); + } + + this.index = index; + } +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/src/com/ibm/wala/shrikeCT/ExceptionsReader.java b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeCT/ExceptionsReader.java new file mode 100644 index 000000000..850c91fda --- /dev/null +++ b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeCT/ExceptionsReader.java @@ -0,0 +1,52 @@ +/******************************************************************************* + * 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.shrikeCT; + +/** + * This class reads Exceptions attributes. + */ +public final class ExceptionsReader extends ClassReaderAttribute { + /** + * Build a reader for the attribute 'iter'. + */ + public ExceptionsReader(ClassReader.AttrIterator iter) throws InvalidClassFileException { + super(iter, "Exceptions"); + + checkSize(attr, 8); + int count = cr.getUShort(attr + 6); + checkSizeEquals(attr + 8, 2 * count); + } + + /** + * @return the indices of the constant pool items for the exceptions + */ + public int[] getRawTable() { + int count = cr.getUShort(attr + 6); + int[] r = new int[count]; + for (int i = 0; i < r.length; i++) { + r[i] = cr.getUShort(attr + 8 + i * 2); + } + return r; + } + + /** + * @return the classes of exceptions that can be thrown by the method + */ + public String[] getClasses() throws InvalidClassFileException { + int count = cr.getUShort(attr + 6); + String[] r = new String[count]; + ConstantPoolParser cp = cr.getCP(); + for (int i = 0; i < r.length; i++) { + r[i] = cp.getCPClass(cr.getUShort(attr + 8 + i * 2)); + } + return r; + } +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/src/com/ibm/wala/shrikeCT/ExceptionsWriter.java b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeCT/ExceptionsWriter.java new file mode 100644 index 000000000..3a01032e7 --- /dev/null +++ b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeCT/ExceptionsWriter.java @@ -0,0 +1,60 @@ +/******************************************************************************* + * 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.shrikeCT; + +/** + * This class builds serializable Exceptions attributes. + */ +public final class ExceptionsWriter extends ClassWriter.Element { + private int attrID; + private int[] table; + + /** + * Build an empty writer. + */ + public ExceptionsWriter(ClassWriter w) { + attrID = w.addCPUtf8("Exceptions"); + } + + public int getSize() { + return table == null ? 8 : 8 + table.length * 2; + } + + public int copyInto(byte[] buf, int offset) { + ClassWriter.setUShort(buf, offset, attrID); + ClassWriter.setInt(buf, offset + 2, getSize() - 6); + ClassWriter.setUShort(buf, offset + 6, table == null ? 0 : table.length); + offset += 8; + if (table != null) { + for (int i = 0; i < table.length; i++) { + ClassWriter.setUShort(buf, offset, table[i]); + offset += 2; + } + } + return offset; + } + + /** + * Set the list of exceptions that can be thrown. + * + * @param exceptions + * an array of indices to constant pool Class entries + */ + public void setRawTable(int[] exceptions) { + for (int i = 0; i < exceptions.length; i++) { + if (exceptions[i] < 1 || exceptions[i] > 0xFFFF) { + throw new IllegalArgumentException("Invalid CP index: " + exceptions[i]); + } + } + + this.table = exceptions; + } +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/src/com/ibm/wala/shrikeCT/InnerClassesReader.java b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeCT/InnerClassesReader.java new file mode 100644 index 000000000..24bbbdf95 --- /dev/null +++ b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeCT/InnerClassesReader.java @@ -0,0 +1,39 @@ +/******************************************************************************* + * 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.shrikeCT; + +/** + * This class reads InnerClasses attributes. + */ +public final class InnerClassesReader extends ClassReaderAttribute { + /** + * Build a reader for the attribute 'iter'. + */ + public InnerClassesReader(ClassReader.AttrIterator iter) throws InvalidClassFileException { + super(iter, "InnerClasses"); + + checkSize(attr, 8); + int count = cr.getUShort(attr + 6); + checkSizeEquals(attr + 8, 8 * count); + } + + /** + * @return the raw values that make up this attribute + */ + public int[] getRawTable() { + int count = cr.getUShort(attr + 6); + int[] r = new int[count * 4]; + for (int i = 0; i < r.length; i++) { + r[i] = cr.getUShort(attr + 8 + i * 2); + } + return r; + } +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/src/com/ibm/wala/shrikeCT/InnerClassesWriter.java b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeCT/InnerClassesWriter.java new file mode 100644 index 000000000..1d19cbc4c --- /dev/null +++ b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeCT/InnerClassesWriter.java @@ -0,0 +1,66 @@ +/******************************************************************************* + * 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.shrikeCT; + +/** + * This class builds serializable InnerClasses attributes. + */ +public final class InnerClassesWriter extends ClassWriter.Element { + private int attrID; + private int[] table; + + /** + * Build an empty writer. + */ + public InnerClassesWriter(ClassWriter w) { + attrID = w.addCPUtf8("InnerClasses"); + } + + public int getSize() { + return table == null ? 8 : 8 + table.length * 2; + } + + public int copyInto(byte[] buf, int offset) { + ClassWriter.setUShort(buf, offset, attrID); + ClassWriter.setInt(buf, offset + 2, getSize() - 6); + ClassWriter.setUShort(buf, offset + 6, table == null ? 0 : table.length); + offset += 8; + if (table != null) { + for (int i = 0; i < table.length; i++) { + ClassWriter.setUShort(buf, offset, table[i]); + offset += 2; + } + } + return offset; + } + + /** + * Set the raw values that make up this attribute + */ + public void setRawTable(int[] classes) { + if (classes.length % 4 != 0) { + throw new IllegalArgumentException("Invalid raw table length: " + classes.length); + } + for (int i = 0; i < classes.length; i += 4) { + if (classes[i] < 1 || classes[i] > 0xFFFF) { + throw new IllegalArgumentException("Invalid CP index: " + classes[i]); + } + if (classes[i + 1] < 0 || classes[i + 1] > 0xFFFF) { + throw new IllegalArgumentException("Invalid CP index: " + classes[i]); + } + if (classes[i + 2] < 0 || classes[i + 2] > 0xFFFF) { + throw new IllegalArgumentException("Invalid CP index: " + classes[i]); + } + } + + this.table = classes; + } +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/src/com/ibm/wala/shrikeCT/InvalidClassFileException.java b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeCT/InvalidClassFileException.java new file mode 100644 index 000000000..65887736f --- /dev/null +++ b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeCT/InvalidClassFileException.java @@ -0,0 +1,41 @@ +/******************************************************************************* + * 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.shrikeCT; + +/** + * This exception is thrown when we detect that the incoming class file data was + * not a valid class file. + */ +public class InvalidClassFileException extends Exception { + + private static final long serialVersionUID = -6224203694783674259L; + private int offset; + + /** + * The incoming class file is invalid. + * + * @param offset + * the offset within the data where the invalidity was detected + * @param s + * the reason the data is invalid + */ + public InvalidClassFileException(int offset, String s) { + super("Class file invalid at " + offset + ": " + s); + this.offset = offset; + } + + /** + * @return the offset within the data where the problem was detected + */ + public int getOffset() { + return offset; + } +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/src/com/ibm/wala/shrikeCT/LineNumberTableReader.java b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeCT/LineNumberTableReader.java new file mode 100644 index 000000000..f7e50e0ed --- /dev/null +++ b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeCT/LineNumberTableReader.java @@ -0,0 +1,104 @@ +/******************************************************************************* + * 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.shrikeCT; + +/** + * This class reads LineNumberTable attributes. + * + * Instead of constructing a LineNumberTableReader directly, consider just + * calling LineNumberTableReader.makeBytecodeToSourceMap for convenient access + * to aggregate line number data from all the LineNumberTable attributes for a + * given Code. + */ +public final class LineNumberTableReader extends ClassReaderAttribute { + /** + * Build a reader for a LineNumberTable attribute. + */ + public LineNumberTableReader(ClassReader.AttrIterator iter) throws InvalidClassFileException { + super(iter, "LineNumberTable"); + + int offset = attr + 6; + checkSize(offset, 2); + int count = cr.getUShort(offset); + offset += 2; + checkSize(offset, count * 4); + } + + /** + * @return the raw line number table data, a flattened sequence of (startPC, + * lineNumber) pairs + */ + public int[] getRawTable() { + int count = cr.getUShort(attr + 6); + int[] r = new int[count * 2]; + int offset = attr + 8; + for (int i = 0; i < r.length; i++) { + r[i] = cr.getUShort(offset); + offset += 2; + } + return r; + } + + /** + * Construct a "bytecode to source" map for the given code. This method + * aggregates all the LineNumberTable attributes for the code into one handy + * data structure. + * + * @return an array mapping each byte of the bytecode bytes to the line number + * that that byte belongs to, or null if there is no line number data + * in the Code + */ + public static int[] makeBytecodeToSourceMap(CodeReader code) throws InvalidClassFileException { + int[] r = null; + ClassReader cr = code.getClassReader(); + + ClassReader.AttrIterator iter = new ClassReader.AttrIterator(); + code.initAttributeIterator(iter); + for (; iter.isValid(); iter.advance()) { + if (iter.getName().equals("LineNumberTable")) { + if (r == null) { + r = new int[code.getBytecodeLength()]; + } + + // check length + new LineNumberTableReader(iter); + int attr = iter.getRawOffset(); + int count = cr.getUShort(attr + 6); + int offset = attr + 8; + for (int j = 0; j < count; j++) { + int startPC = cr.getUShort(offset); + int lineNum = cr.getUShort(offset + 2); + offset += 4; + + if (startPC < 0 || startPC >= r.length) { + throw new InvalidClassFileException(offset, "Invalid bytecode offset " + startPC + " in LineNumberTable"); + } + r[startPC] = lineNum; + } + } + } + + if (r != null) { + // fill in gaps in the old line number map + int last = 0; + for (int i = 0; i < r.length; i++) { + int cur = r[i]; + if (cur == 0) { + r[i] = last; + } else { + last = cur; + } + } + } + + return r; + } +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/src/com/ibm/wala/shrikeCT/LineNumberTableWriter.java b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeCT/LineNumberTableWriter.java new file mode 100644 index 000000000..d17523b65 --- /dev/null +++ b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeCT/LineNumberTableWriter.java @@ -0,0 +1,104 @@ +/******************************************************************************* + * 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.shrikeCT; + +/** + * This class helps emit LineNumberTable attributes. + */ +public final class LineNumberTableWriter extends ClassWriter.Element { + private int attrID; + private int[] rawTable = emptyTable; + + private static final int[] emptyTable = new int[0]; + + /** + * Build an empty LineNumberTable. + */ + public LineNumberTableWriter(ClassWriter w) { + attrID = w.addCPUtf8("LineNumberTable"); + } + + /** + * Set the raw table entries. Consider calling + * LineNumberTableWriter.makeRawTable to build the raw entries. + * + * @param table + * a flattened sequence of (startPC, lineNumber) pairs + */ + public void setRawTable(int[] table) { + if (table == null) { + table = emptyTable; + } + + if (table.length % 2 != 0) { + throw new IllegalArgumentException("Line number table has bad length: " + table.length); + } + if (table.length / 2 > 0xFFFF) { + throw new IllegalArgumentException("Too many line number table entries: " + table.length / 2); + } + for (int i = 0; i < table.length; i++) { + int v = table[i]; + if (v < 0 || v > 0xFFFF) { + throw new IllegalArgumentException("Bad line number table entry at " + i + ": " + v); + } + } + + rawTable = table; + } + + public int getSize() { + return 8 + rawTable.length * 2; + } + + public int copyInto(byte[] buf, int offset) { + ClassWriter.setUShort(buf, offset, attrID); + ClassWriter.setInt(buf, offset + 2, 2 + rawTable.length * 2); + ClassWriter.setUShort(buf, offset + 6, rawTable.length / 2); + offset += 8; + for (int i = 0; i < rawTable.length; i++) { + ClassWriter.setUShort(buf, offset, rawTable[i]); + offset += 2; + } + + return offset; + } + + /** + * @param newLineMap + * an array indexed by bytecode offset, mapping each bytecode offset + * to its line number (or 0 if there is no line or it's not known) + * @return the line numbers in "raw" format, a flattened sequence of (startPC, + * lineNumber) pairs + */ + public static int[] makeRawTable(int[] newLineMap) { + int rawCount = 0; + int last = -1; + for (int i = 0; i < newLineMap.length; i++) { + int next = newLineMap[i]; + if (next != last) { + rawCount++; + } + } + int[] rawTable = new int[rawCount * 2]; + last = -1; + int index = 0; + for (int i = 0; i < newLineMap.length; i++) { + int next = newLineMap[i]; + if (next != last) { + rawTable[index] = i; + rawTable[index + 1] = next; + index += 2; + } + } + return rawTable; + } +} + diff --git a/com.ibm.wala.shrike/src/com/ibm/wala/shrikeCT/LocalVariableTableReader.java b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeCT/LocalVariableTableReader.java new file mode 100644 index 000000000..8dc8512b6 --- /dev/null +++ b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeCT/LocalVariableTableReader.java @@ -0,0 +1,120 @@ +/******************************************************************************* + * 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.shrikeCT; + +/** + * This class reads LocalVariableTable attributes. + * + * Instead of constructing a LocalVariableTable directly, consider just calling + * LocalVariableTable.makeVarMap for convenient access to aggregate local + * variable data from all the LocalVariableTable attributes for a given Code. + */ +public final class LocalVariableTableReader extends ClassReaderAttribute { + public LocalVariableTableReader(ClassReader.AttrIterator iter) throws InvalidClassFileException { + super(iter, "LocalVariableTable"); + + int offset = attr + 6; + checkSize(offset, 2); + int count = cr.getUShort(offset); + offset += 2; + checkSize(offset, count * 10); + } + + /** + * @return the raw line number table data, a flattened sequence of (startPC, + * PClength, nameIndex, typeIndex, var) tuples + */ + public int[] getRawTable() { + int count = cr.getUShort(attr + 6); + int[] r = new int[count * 5]; + int offset = attr + 8; + for (int i = 0; i < r.length; i++) { + r[i] = cr.getUShort(offset); + offset += 2; + } + return r; + } + + private static int[] makeVarVector(int[] curVector, int varIndex, int nameIndex, int typeIndex) { + int[] newVector; + if (curVector == null) { + newVector = new int[(varIndex + 1) * 2]; + } else { + newVector = new int[Math.max(curVector.length, (varIndex + 1) * 2)]; + System.arraycopy(curVector, 0, newVector, 0, curVector.length); + } + newVector[varIndex * 2] = nameIndex; + newVector[varIndex * 2 + 1] = typeIndex; + return newVector; + } + + /** + * @return an array mapping bytecode offsets to arrays representing the local + * variable maps for each offset; a local variable map is represented + * as an array of localVars*2 elements, containing a pair (nameIndex, + * typeIndex) for each local variable; a pair (0,0) indicates there is + * no information for that local variable at that offset + */ + public static int[][] makeVarMap(CodeReader code) throws InvalidClassFileException { + int[][] r = null; + ClassReader cr = code.getClassReader(); + + ClassReader.AttrIterator iter = new ClassReader.AttrIterator(); + code.initAttributeIterator(iter); + for (; iter.isValid(); iter.advance()) { + if (iter.getName().equals("LocalVariableTable")) { + if (r == null) { + r = new int[code.getBytecodeLength()][]; + } + + // check length + new LocalVariableTableReader(iter); + int attr = iter.getRawOffset(); + int count = cr.getUShort(attr + 6); + int offset = attr + 8; + for (int j = 0; j < count; j++) { + int startPC = cr.getUShort(offset); + int length = cr.getUShort(offset + 2); + int nameIndex = cr.getUShort(offset + 4); + int typeIndex = cr.getUShort(offset + 6); + int varIndex = cr.getUShort(offset + 8); + offset += 10; + + if (varIndex < 0) { + throw new InvalidClassFileException(offset, "Invalid variable index " + varIndex + " in LocalVariableTable"); + } else if (startPC < 0) { + throw new InvalidClassFileException(offset, "Invalid startPC " + startPC + " in LocalVariableTable"); + } else if (startPC + length > r.length) { + throw new InvalidClassFileException(offset, "Invalid startPC+length " + (startPC + length) + " > " + r.length + + " in LocalVariableTable"); + } + + int rangeStart = startPC; + while (rangeStart < startPC + length) { + int rangeLength = 1; + while (rangeStart + rangeLength < startPC + length && r[rangeStart + rangeLength] == r[rangeStart]) { + rangeLength++; + } + + int[] newVector = makeVarVector(r[rangeStart], varIndex, nameIndex, typeIndex); + for (int k = rangeStart; k < rangeStart + rangeLength; k++) { + r[k] = newVector; + } + + rangeStart += rangeLength; + } + } + } + } + + return r; + } +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/src/com/ibm/wala/shrikeCT/LocalVariableTableWriter.java b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeCT/LocalVariableTableWriter.java new file mode 100644 index 000000000..624b2f8b0 --- /dev/null +++ b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeCT/LocalVariableTableWriter.java @@ -0,0 +1,145 @@ +/******************************************************************************* + * 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.shrikeCT; + +import java.util.Arrays; + +/** + * This class helps emit LocalVariableTable attributes. + */ +public final class LocalVariableTableWriter extends ClassWriter.Element { + private int attrID; + private int[] rawTable = emptyTable; + + private static final int[] emptyTable = new int[0]; + + /** + * Create a blank LocalVariableTable. + */ + public LocalVariableTableWriter(ClassWriter w) { + attrID = w.addCPUtf8("LocalVariableTable"); + } + + /** + * Set the raw local variable table values. Consider using + * LocalVariableTableWriter.makeRawTable to build the raw values. + * + * @param table + * the raw values, a flattened sequence of (startPC, length, + * nameIndex, typeIndex, var) tuples + */ + public void setRawTable(int[] table) { + if (table == null) { + table = emptyTable; + } + + if (table.length % 5 != 0) { + throw new IllegalArgumentException("Local variable table has bad length: " + table.length); + } + if (table.length / 5 > 0xFFFF) { + throw new IllegalArgumentException("Too many local variable table entries: " + table.length / 5); + } + for (int i = 0; i < table.length; i++) { + int v = table[i]; + if (v < 0 || v > 0xFFFF) { + throw new IllegalArgumentException("Bad local variable table entry at " + i + ": " + v); + } + } + + rawTable = table; + } + + public int getSize() { + return 8 + rawTable.length * 2; + } + + public int copyInto(byte[] buf, int offset) { + ClassWriter.setUShort(buf, offset, attrID); + ClassWriter.setInt(buf, offset + 2, 2 + rawTable.length * 2); + ClassWriter.setUShort(buf, offset + 6, rawTable.length / 5); + offset += 8; + for (int i = 0; i < rawTable.length; i++) { + ClassWriter.setUShort(buf, offset, rawTable[i]); + offset += 2; + } + + return offset; + } + + /** + * Build a raw local variable table from a formatted variable map. + * + * @param varMap + * an array mapping bytecode offsets to a variable map for each + * offset; a variable map is a array of 2*localVars elements, + * containing a (nameIndex, typeIndex) for each local variable; the + * pair (0,0) indicates that there is no information about that local + * variable at that offset + */ + public static int[] makeRawTable(int[][] varMap) { + int varCount = 0; + for (int i = 0; i < varMap.length; i++) { + if (varMap[i] != null) { + varCount = Math.max(varCount, varMap[i].length); + } + } + varCount /= 2; + + int[] entries = new int[20]; + int[] varEnd = new int[varCount]; + Arrays.fill(varEnd, -1); + int[] lastVector = null; + int entryCount = 0; + for (int i = 0; i < varMap.length; i++) { + if (varMap[i] != lastVector) { + lastVector = varMap[i]; + + if (lastVector != null) { + for (int k = 0; k < lastVector.length / 2; k++) { + if (lastVector[k * 2] > 0 && i >= varEnd[k]) { + int entryOffset = entryCount * 5; + entryCount++; + if (entryCount * 5 > entries.length) { + int[] newEntries = new int[entries.length * 2]; + System.arraycopy(entries, 0, newEntries, 0, entries.length); + entries = newEntries; + } + int nameIndex = lastVector[k * 2]; + int typeIndex = lastVector[k * 2 + 1]; + int end = i + 1; + while (end < varMap.length) { + if (varMap[end] == null || k * 2 >= varMap[end].length || varMap[end][k * 2] != nameIndex + || varMap[end][k * 2 + 1] != typeIndex) { + break; + } + end++; + } + varEnd[k] = end; + entries[entryOffset] = i; + entries[entryOffset + 1] = end - i; + entries[entryOffset + 2] = nameIndex; + entries[entryOffset + 3] = typeIndex; + entries[entryOffset + 4] = k; + } + } + } + } + } + + if (entryCount == 0) { + return null; + } else { + int[] r = new int[entryCount * 5]; + System.arraycopy(entries, 0, r, 0, r.length); + return r; + } + } +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/src/com/ibm/wala/shrikeCT/SourceDebugExtensionReader.java b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeCT/SourceDebugExtensionReader.java new file mode 100644 index 000000000..8a33d4dc7 --- /dev/null +++ b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeCT/SourceDebugExtensionReader.java @@ -0,0 +1,25 @@ +/******************************************************************************* + * 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.shrikeCT; + +public class SourceDebugExtensionReader extends ClassReaderAttribute { + public SourceDebugExtensionReader(ClassReader.AttrIterator iter) throws InvalidClassFileException { + super(iter, "SourceDebugExtension"); + + checkSize(attr, 6); + + + } + + +} + + diff --git a/com.ibm.wala.shrike/src/com/ibm/wala/shrikeCT/SourceDebugExtensionWriter.java b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeCT/SourceDebugExtensionWriter.java new file mode 100644 index 000000000..4412c0583 --- /dev/null +++ b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeCT/SourceDebugExtensionWriter.java @@ -0,0 +1,59 @@ +/******************************************************************************* + * 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.shrikeCT; + +import java.io.UnsupportedEncodingException; + +import com.ibm.wala.shrikeCT.ClassWriter; + +public class SourceDebugExtensionWriter extends ClassWriter.Element { + private int attrID; + private byte[] table; + + public SourceDebugExtensionWriter(ClassWriter w){ + attrID = w.addCPUtf8("SourceDebugExtension"); + } + + public int getSize() { + return table == null ? 6 : 6 + table.length; + } + + public int copyInto(byte[] buf, int offset) { + ClassWriter.setUShort(buf, offset, attrID); + ClassWriter.setInt(buf, offset + 2, getSize() - 6); + offset += 6; + if (table != null) { + for (int i = 0; i < table.length; i++) { + ClassWriter.setUByte(buf, offset, table[i]); + offset++; + } + } + return offset; + } + + public void setRawTable(byte[] sourceDebug){ + for(int i = 0; i < sourceDebug.length ; i++){ + if (sourceDebug[i] < 1 || sourceDebug[i] > 0xFFFF) { + throw new IllegalArgumentException("Invalid CP index: " + sourceDebug[i]); + } + } + this.table = sourceDebug; + } + + public void setDebugInfo(String sourceDebug){ + try { + byte[] bytes = sourceDebug.getBytes("UTF8"); + setRawTable(bytes); + } catch (UnsupportedEncodingException e){ + System.err.println(e); + } + } +} diff --git a/com.ibm.wala.shrike/src/com/ibm/wala/shrikeCT/SourceFileReader.java b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeCT/SourceFileReader.java new file mode 100644 index 000000000..c89c56173 --- /dev/null +++ b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeCT/SourceFileReader.java @@ -0,0 +1,32 @@ +/******************************************************************************* + * 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.shrikeCT; + +/** + * This class reads SourceFile attributes. + */ +public final class SourceFileReader extends ClassReaderAttribute { + /** + * Build a reader for the attribute 'iter'. + */ + public SourceFileReader(ClassReader.AttrIterator iter) throws InvalidClassFileException { + super(iter, "SourceFile"); + + checkSizeEquals(attr + 6, 2); + } + + /** + * @return the index of the constant pool item holding the value + */ + public int getSourceFileCPIndex() { + return cr.getUShort(attr + 6); + } +} \ No newline at end of file diff --git a/com.ibm.wala.shrike/src/com/ibm/wala/shrikeCT/SourceFileWriter.java b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeCT/SourceFileWriter.java new file mode 100644 index 000000000..3237b1dbd --- /dev/null +++ b/com.ibm.wala.shrike/src/com/ibm/wala/shrikeCT/SourceFileWriter.java @@ -0,0 +1,58 @@ +/******************************************************************************* + * 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.shrikeCT; + +/** + * This class builds serializable SourceFile attributes. + * + * After constructing a SourceFileWriter, you must call setSourceFileCPIndex. + */ +public final class SourceFileWriter extends ClassWriter.Element { + private int attrID; + private int index = -1; + + /** + * Build an empty writer. + */ + public SourceFileWriter(ClassWriter w) { + attrID = w.addCPUtf8("SourceFile"); + } + + private void verify() { + if (index < 0) { + throw new IllegalArgumentException("The value's constant pool index is not set"); + } + } + + public int getSize() { + verify(); + return 8; + } + + public int copyInto(byte[] buf, int offset) { + verify(); + ClassWriter.setUShort(buf, offset, attrID); + ClassWriter.setInt(buf, offset + 2, 2); + ClassWriter.setUShort(buf, offset + 6, index); + return offset + 8; + } + + /** + * Set the index of the constant pool item holding the source file name. + */ + public void setSourceFileCPIndex(int index) { + if (index < 1 || index > 0xFFFF) { + throw new IllegalArgumentException("Invalid CP index: " + index); + } + + this.index = index; + } +} \ No newline at end of file