From ef3eb48fc2a1d6f9d8918a366b272bacf95bc4b1 Mon Sep 17 00:00:00 2001 From: Evan Battaglia Date: Mon, 10 Mar 2008 15:18:48 -0700 Subject: [PATCH] WALA patch: fixe cast.js import --- ...WALA-bugfixes-200803101028-against-v1.1.2.patch | 1053 ++++++++++++++++++++ 1 file changed, 1053 insertions(+) create mode 100644 Svelte/WALA-bugfixes-200803101028-against-v1.1.2.patch diff --git a/Svelte/WALA-bugfixes-200803101028-against-v1.1.2.patch b/Svelte/WALA-bugfixes-200803101028-against-v1.1.2.patch new file mode 100644 index 0000000..7307698 --- /dev/null +++ b/Svelte/WALA-bugfixes-200803101028-against-v1.1.2.patch @@ -0,0 +1,1053 @@ +diff --git a/com.ibm.wala.cast.java.test/src/com/ibm/wala/cast/java/test/JavaIRTests.java b/com.ibm.wala.cast.java.test/src/com/ibm/wala/cast/java/test/JavaIRTests.java +index 691baf7..05489ef 100644 +--- a/com.ibm.wala.cast.java.test/src/com/ibm/wala/cast/java/test/JavaIRTests.java ++++ b/com.ibm.wala.cast.java.test/src/com/ibm/wala/cast/java/test/JavaIRTests.java +@@ -14,6 +14,7 @@ + package com.ibm.wala.cast.java.test; + + import java.io.File; ++import java.util.ArrayList; + import java.util.Arrays; + import java.util.Collection; + import java.util.Iterator; +@@ -25,6 +26,7 @@ import junit.framework.Assert; + import com.ibm.wala.cast.java.client.JavaSourceAnalysisEngine; + import com.ibm.wala.cast.java.ipa.slicer.AstJavaSlicer; + import com.ibm.wala.cast.java.loader.JavaSourceLoaderImpl; ++import com.ibm.wala.cast.java.ssa.EnclosingObjectReference; + import com.ibm.wala.classLoader.IClass; + import com.ibm.wala.core.tests.callGraph.CallGraphTestUtil; + import com.ibm.wala.core.tests.slicer.SlicerTest; +@@ -35,6 +37,8 @@ import com.ibm.wala.ipa.callgraph.CGNode; + import com.ibm.wala.ipa.callgraph.CallGraph; + import com.ibm.wala.ipa.callgraph.Entrypoint; + import com.ibm.wala.ipa.callgraph.impl.Util; ++import com.ibm.wala.ipa.callgraph.propagation.InstanceKey; ++import com.ibm.wala.ipa.callgraph.propagation.LocalPointerKey; + import com.ibm.wala.ipa.callgraph.propagation.PointerAnalysis; + import com.ibm.wala.ipa.cha.IClassHierarchy; + import com.ibm.wala.ipa.slicer.SDG; +@@ -374,6 +378,94 @@ public class JavaIRTests extends IRTests { + }), true); + } + ++ public void testInnerClassA() { ++ Pair x = runTest(singleTestSrc(), rtJar, simpleTestEntryPoint(), new ArrayList(), true); ++ ++ // can't do an IRAssertion() -- we need the pointer analysis ++ ++ CallGraph cg = (CallGraph) x.fst; ++ PointerAnalysis pa = (PointerAnalysis) x.snd; ++ ++ Iterator iter = cg.iterator(); ++ while ( iter.hasNext() ) { ++ CGNode n = iter.next(); ++ ++ // assume in the test we have one enclosing instruction for each of the methods here. ++ String methodSigs[] = { "InnerClassA$AB.getA_X_from_AB()I", ++ "InnerClassA$AB.getA_X_thru_AB()I", ++ "InnerClassA$AB$ABSubA.getA_X()I", ++ "InnerClassA$AB$ABA$ABAA.getABA_X()I", ++ "InnerClassA$AB$ABA$ABAA.getA_X()I", ++ "InnerClassA$AB$ABA$ABAB.getABA_X()I", ++ "InnerClassA$AB$ABSubA$ABSubAA.getABA_X()I", ++ "InnerClassA$AB$ABSubA$ABSubAA.getA_X()I", }; ++ ++ // each type suffixed by "," ++ String ikConcreteTypeStrings[ ]= { ++ "LInnerClassA,", ++ "LInnerClassA,", ++ "LInnerClassA,", ++ "LInnerClassA$AB$ABSubA,LInnerClassA$AB$ABA,", ++ "LInnerClassA,", ++ "LInnerClassA$AB$ABA,", ++ "LInnerClassA$AB$ABSubA,", ++ "LInnerClassA,", ++ }; ++ ++ Assert.assertTrue ( "Buggy test", methodSigs.length == ikConcreteTypeStrings.length ); ++ for ( int i = 0; i < methodSigs.length; i++ ) { ++ if ( n.getMethod().getSignature().equals(methodSigs[i]) ) { ++ // find enclosing instruction ++ for ( SSAInstruction instr: n.getIR().getInstructions() ) { ++ if ( instr instanceof EnclosingObjectReference ) { ++ String allIks = ""; ++ for (InstanceKey ik: pa.getPointsToSet(new LocalPointerKey(n,instr.getDef()))) ++ allIks += ik.getConcreteType().getName() +","; ++ System.out.printf("in method %s, got ik %s\n", methodSigs[i], allIks); ++ ++ Assert.assertTrue("assertion failed: expecting ik " + ikConcreteTypeStrings[i] + " in method " + methodSigs[i] + ", got " + allIks + "\n", ++ allIks.equals(ikConcreteTypeStrings[i])); ++ ++ break; ++ } ++ } ++ } ++ } ++ } ++ ++ ++ } ++ ++ public void testInnerClassSuper() { ++ Pair x = runTest(singleTestSrc(), rtJar, simpleTestEntryPoint(), new ArrayList(), true); ++ ++ // can't do an IRAssertion() -- we need the pointer analysis ++ ++ CallGraph cg = (CallGraph) x.fst; ++ PointerAnalysis pa = (PointerAnalysis) x.snd; ++ ++ Iterator iter = cg.iterator(); ++ while ( iter.hasNext() ) { ++ CGNode n = iter.next(); ++ if ( n.getMethod().getSignature().equals("LInnerClassSuper$SuperOuter.test()V") ) { ++ // find enclosing instruction ++ for ( SSAInstruction instr: n.getIR().getInstructions() ) { ++ if ( instr instanceof EnclosingObjectReference ) { ++ String allIks = ""; ++ for (InstanceKey ik: pa.getPointsToSet(new LocalPointerKey(n,instr.getDef()))) ++ allIks += ik.getConcreteType().getName() +","; ++ Assert.assertTrue("assertion failed: expecting ik \"LSub,\" in method, got \"" + allIks + "\"\n", ++ allIks.equals("LSub,")); ++ ++ break; ++ } ++ } ++ } ++ } ++ ++ ++ } ++ + public void testLocalClass() { + runTest(singleTestSrc(), rtJar, simpleTestEntryPoint(), Arrays.asList( + +diff --git a/com.ibm.wala.cast.java.test/src/com/ibm/wala/cast/java/test/JavaOneContainerIRTests.java b/com.ibm.wala.cast.java.test/src/com/ibm/wala/cast/java/test/JavaOneContainerIRTests.java +new file mode 100644 +index 0000000..de1024f +--- /dev/null ++++ b/com.ibm.wala.cast.java.test/src/com/ibm/wala/cast/java/test/JavaOneContainerIRTests.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 ++ *****************************************************************************/ ++/* ++ * Created on Oct 21, 2005 ++ */ ++package com.ibm.wala.cast.java.test; ++ ++import java.io.File; ++import java.util.ArrayList; ++ ++import com.ibm.wala.cast.java.client.JavaSourceAnalysisEngine; ++import com.ibm.wala.cast.java.client.impl.ZeroOneContainerCFABuilderFactory; ++import com.ibm.wala.core.tests.callGraph.CallGraphTestUtil; ++import com.ibm.wala.eclipse.util.EclipseProjectPath; ++import com.ibm.wala.ipa.callgraph.AnalysisCache; ++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.Entrypoint; ++import com.ibm.wala.ipa.callgraph.impl.Util; ++import com.ibm.wala.ipa.cha.IClassHierarchy; ++ ++public class JavaOneContainerIRTests extends IRTests { ++ public JavaOneContainerIRTests(String name) { ++ super(name); ++ } ++ ++ protected JavaSourceAnalysisEngine getAnalysisEngine(final String[] mainClassDescriptors) { ++ JavaSourceAnalysisEngine engine = new JavaSourceAnalysisEngine() { ++ @Override ++ protected CallGraphBuilder getCallGraphBuilder(IClassHierarchy cha, ++ AnalysisOptions options, AnalysisCache cache) { ++ return new ZeroOneContainerCFABuilderFactory().make(options, cache, cha, scope, false); ++ } ++ ++ protected Iterable makeDefaultEntrypoints(AnalysisScope scope, IClassHierarchy cha) { ++ return Util.makeMainEntrypoints(EclipseProjectPath.SOURCE_REF, cha, mainClassDescriptors); ++ } ++ }; ++ engine.setExclusionsFile(CallGraphTestUtil.REGRESSION_EXCLUSIONS); ++ return engine; ++ } ++ ++ protected String singleInputForTest() { ++ return getName().substring(4) + ".java"; ++ } ++ ++ protected String singleInputForTestNoExt() { ++ return getName().substring(4); ++ } ++ ++ protected String singlePkgInputForTest(String pkgName) { ++ return pkgName + File.separator + getName().substring(4) + ".java"; ++ } ++ ++ public void testInnerClassLexicalReads() { ++ // throws UnimplementedError on failure (expecting ScopeMappingInstanceKeys but not generating them) ++ runTest(singleTestSrc(), rtJar, simpleTestEntryPoint(), new ArrayList(), true); ++ } ++} +diff --git a/com.ibm.wala.cast.java.test/testSrc/InnerClassA.java b/com.ibm.wala.cast.java.test/testSrc/InnerClassA.java +new file mode 100644 +index 0000000..f51541a +--- /dev/null ++++ b/com.ibm.wala.cast.java.test/testSrc/InnerClassA.java +@@ -0,0 +1,125 @@ ++// other stranger test cases ++// ++// combininations of: ++// o.new() form ++// function calls ++// getting enclosings from one AND multiple levels up ++// new Foo() which requires an enclosing instruction before (ie calling new Inner() from ReallyInner() ++// invariants and non-invariants (immediate 'new' in that function) ++// subclasses ++ ++public class InnerClassA { ++ int a_x; ++ ++ public static void main(String args[]) { ++ // prints out 5 5 9 7 5 5 7 5 7 5 ++ InnerClassA a = new InnerClassA(); ++ AA aa = a.new AA(); ++ AB ab = aa.makeAB(); ++ a.a_x = 5; ++ ++ // tests ++ int myx = ab.getA_X_from_AB(); ++ System.out.println(myx); // 5 ++ int myx2 = ab.getA_X_thru_AB(); ++ System.out.println(myx2); // 5 ++ ++ aa.doSomeCrazyStuff(); ++ } ++ ++ public int getA_X() { ++ return a_x; ++ } ++ ++ class AA { ++ int a2a_var; ++ ++ public AB makeAB() { ++ return new AB(); ++ } ++ ++ public void doSomeCrazyStuff() { ++ AB ab = new AB(); ++ AB.ABSubA absuba = ab.new ABSubA(); ++ absuba.aba_x = 7; ++ AB.ABA.ABAA abaa2 = ab.new ABA().new ABAA(); // just used to add ABA instance key in ABAA.getABA_X() ++ ++ AB.ABA aba = ab.new ABA(); ++ aba.aba_x = 9; ++ AB.ABA.ABAB abab = aba.new ABAB(); ++ System.out.println(abab.getABA_X()); // 9 ++ ++ AB.ABA.ABAA abaa = absuba.new ABAA(); ++ int myaba_x = abaa.getABA_X(); ++ int mya_x = abaa.getA_X(); ++ System.out.println(myaba_x); // 7 ++ System.out.println(mya_x); // 5 ++ ++ ++ doMoreWithABSubA(absuba); ++ } ++ ++ private void doMoreWithABSubA(InnerClassA.AB.ABSubA absuba) { ++ System.out.println(absuba.getA_X()); // 5 ++ ++ AB.ABSubA.ABSubAA absubaa = absuba.new ABSubAA(); ++ int myaba_x2 = absubaa.getABA_X(); ++ int mya_x2 = absubaa.getA_X(); ++ System.out.println(myaba_x2); // 7 ++ System.out.println(mya_x2); // 5 ++ // TODO Auto-generated method stub ++ ++ AB.ABA.ABAA abaa = absubaa.makeABAA(); ++ int myaba_x3 = abaa.getABA_X(); ++ int mya_x3 = abaa.getA_X(); ++ System.out.println(myaba_x3); // 7 ++ System.out.println(mya_x3); // 5 ++ ++ } ++ } ++ ++ class AB { ++ public int getA_X_from_AB() { ++ return a_x; // CHECK enclosing is an A ++ } ++ ++ public int getA_X_thru_AB() { ++ return getA_X(); // CHECK enclosing is an A ++ } ++ ++ class ABA { ++ int aba_x; ++ class ABAA { ++ int getABA_X() { ++ return aba_x; // CHECK enclosing is an ABA or ABSubA ++ } ++ int getA_X() { ++ return a_x; // CHECK enclosing is an A ++ } ++ } ++ class ABAB { ++ int getABA_X() { ++ return aba_x; // CHECK enclosing is an ABA ++ } ++ } ++ } ++ ++ class ABSubA extends ABA { ++ class ABSubAA { ++ int getABA_X() { ++ return aba_x; // CHECK enclosing is an ABSubA ++ } ++ int getA_X() { ++ return a_x; // CHECK enclosing is an A ++ } ++ ABA.ABAA makeABAA() { ++ return new ABAA(); // this new instruction requires us to know that ABSubA is a subclass of ABA. ++ // thus when we call getABA_X() on the result, it will need to find a EORK(this site,class ABA) -> THIS (of type ABSubAA) ++ } ++ } ++ int getA_X() { ++ return a_x; // CHECK enclosing is an A ++ } ++ } ++ } ++} +diff --git a/com.ibm.wala.cast.java.test/testSrc/InnerClassLexicalReads.java b/com.ibm.wala.cast.java.test/testSrc/InnerClassLexicalReads.java +new file mode 100644 +index 0000000..6d15249 +--- /dev/null ++++ b/com.ibm.wala.cast.java.test/testSrc/InnerClassLexicalReads.java +@@ -0,0 +1,47 @@ ++interface IntConstant { ++ int getConstant(); ++} ++ ++public class InnerClassLexicalReads { ++ ++ /* ++ * CAst Instructions: ++ * 2 v3 = new $9$9>@2[9:9] -> [13:3] ++ * 3 invokespecial < Source, LInnerClassLexicalReads/makeIntConstant(I)LIntConstant;/$9$9, ()V > v3 @3 exception:v5[9:9] -> [13:3] ++ * 4 return v3 [9:2] -> [13:4] ++ */ ++ public static IntConstant makeIntConstant(int x) { ++ final int y = x * x; ++ return new IntConstant() { ++// CAst CONSTRUCTOR Instructions: ++// 1 invokespecial < Source, Ljava/lang/Object, ()V > v1 @1 exception:v3[20:9] -> [32:3] ++ ++ /* ++ * CAst Instructions: ++ * 0 v2:com.ibm.wala.ssa.SymbolTable$1@16b18b6 = lexical:y@LInnerClassLexicalReads/makeIntConstant(I)LIntConstant; ++ * 1 return v2:com.ibm.wala.ssa.SymbolTable$1@16b18b6[11:4] -> [11:13] ++ */ ++ public int getConstant() { ++ return y; ++ } ++ }; ++ } ++ ++ ++ /* ++ * CAst Instructions: ++ * 1 v2:com.ibm.wala.ssa.SymbolTable$1@4272b2 = invokestatic < Source, LInnerClassLexicalReads, makeIntConstant(I)LIntConstant; > v3:#123 @1 exception:v4[17:19] -> [17:39] ++ * 2 v7 = getstatic < Source, Ljava/lang/System, out, >[18:2] -> [18:12] ++ * 3 v8 = invokeinterface < Source, LIntConstant, getConstant()I > v2:com.ibm.wala.ssa.SymbolTable$1@4272b2 @3 exception:v9[18:21] -> [18:37] ++ * 4 invokevirtual < Source, Ljava/io/PrintStream, println(I)V > v7,v8 @4 exception:v10[18:2] -> [18:38] ++ */ ++ public static void main(String args[]) { ++ InnerClassLexicalReads ignored = new InnerClassLexicalReads(); // call this just to make reachable (test checks for unreachable methods) ++ int foo = 5; ++ int haha = foo * foo; ++ IntConstant ic = makeIntConstant(haha); ++ System.out.println(ic.getConstant()); ++ int x = ic.getConstant(); ++ System.out.println(x); ++ } ++} +diff --git a/com.ibm.wala.cast.java.test/testSrc/InnerClassSuper.java b/com.ibm.wala.cast.java.test/testSrc/InnerClassSuper.java +new file mode 100644 +index 0000000..d61a986 +--- /dev/null ++++ b/com.ibm.wala.cast.java.test/testSrc/InnerClassSuper.java +@@ -0,0 +1,19 @@ ++public class InnerClassSuper { ++ int x = 5; ++ class SuperOuter { ++ public void test() { ++ System.out.println(x); ++ } ++ } ++ public static void main(String args[]) { ++ new Sub().new SubInner(); ++ } ++} ++class Sub extends InnerClassSuper { ++ class SubInner { ++ public SubInner() { ++ InnerClassSuper.SuperOuter so = new InnerClassSuper.SuperOuter(); ++ so.test(); ++ } ++ } ++} +\ No newline at end of file +diff --git a/com.ibm.wala.cast.java/src/com/ibm/wala/cast/java/ipa/callgraph/AstJavaSSAPropagationCallGraphBuilder.java b/com.ibm.wala.cast.java/src/com/ibm/wala/cast/java/ipa/callgraph/AstJavaSSAPropagationCallGraphBuilder.java +index 94993c1..b94db65 100644 +--- a/com.ibm.wala.cast.java/src/com/ibm/wala/cast/java/ipa/callgraph/AstJavaSSAPropagationCallGraphBuilder.java ++++ b/com.ibm.wala.cast.java/src/com/ibm/wala/cast/java/ipa/callgraph/AstJavaSSAPropagationCallGraphBuilder.java +@@ -16,6 +16,7 @@ import com.ibm.wala.cast.java.analysis.typeInference.AstJavaTypeInference; + import com.ibm.wala.cast.java.loader.JavaSourceLoaderImpl.JavaClass; + import com.ibm.wala.cast.java.ssa.AstJavaInstructionVisitor; + import com.ibm.wala.cast.java.ssa.AstJavaInvokeInstruction; ++import com.ibm.wala.cast.java.ssa.AstJavaNewEnclosingInstruction; + import com.ibm.wala.cast.java.ssa.EnclosingObjectReference; + import com.ibm.wala.classLoader.IClass; + import com.ibm.wala.fixedpoint.impl.UnaryOperator; +@@ -182,6 +183,14 @@ public class AstJavaSSAPropagationCallGraphBuilder extends AstSSAPropagationCall + super(builder, node); + } + ++ /** ++ * For each of objKey's instance keys ik, adds the constraint lvalKey = EORK(ik,cls), ++ * where EORK(ik,cls) will be made equivalent to the actual enclosing class by ++ * the handleNew() function below. ++ * @param lvalKey ++ * @param cls ++ * @param objKey ++ */ + private void handleEnclosingObject(final PointerKey lvalKey, final IClass cls, final PointerKey objKey) { + SymbolTable symtab = ir.getSymbolTable(); + int objVal; +@@ -246,12 +255,33 @@ public class AstJavaSSAPropagationCallGraphBuilder extends AstSSAPropagationCall + if (iKey != null) { + IClass klass = iKey.getConcreteType(); + ++ // in the case of a AstJavaNewEnclosingInstruction (a new instruction like outer.new Bla()), ++ // we may need to record the instance keys if the pointer key outer is invariant (and thus implicit) ++ InstanceKey enclosingInvariantKeys[] = null; ++ + if (klass instanceof JavaClass) { +- IClass enclosingClass = ((JavaClass) klass).getEnclosingClass(); ++ IClass enclosingClass = ((JavaClass) klass).getEnclosingClass(); // the immediate enclosing class. + if (enclosingClass != null) { + IClass currentCls = node.getMethod().getDeclaringClass(); +- PointerKey objKey = getPointerKeyForLocal(1); +- boolean needIndirection = false; ++ PointerKey objKey; ++ ++ if ( instruction instanceof AstJavaNewEnclosingInstruction ) { ++ ++ ++ int enclosingVal = ((AstJavaNewEnclosingInstruction) instruction).getEnclosing(); ++ SymbolTable symtab = ir.getSymbolTable(); ++ ++ // pk 'outer' is invariant, which means it's implicit, so can't add a constraint with the pointer key. ++ // we should just add constraints directly to the instance keys (below) ++ if ( contentsAreInvariant(symtab, du, enclosingVal) ) ++ enclosingInvariantKeys = getInvariantContents(enclosingVal); ++ ++ // what happens if objKey is implicit but the contents aren't invariant?! (it this possible?) big trouble! ++ ++ objKey = getPointerKeyForLocal(enclosingVal); ++ } ++ else ++ objKey = getPointerKeyForLocal(1); + + Trace.println("class is " + klass + ", enclosing is " + enclosingClass + ", method is " + node.getMethod()); + +@@ -259,31 +289,30 @@ public class AstJavaSSAPropagationCallGraphBuilder extends AstSSAPropagationCall + return; + } + +- while (!getClassHierarchy().isSubclassOf(currentCls, enclosingClass)) { +- Assertions._assert(currentCls instanceof JavaClass); ++ currentCls = enclosingClass; ++ ++ PointerKey x = new EnclosingObjectReferenceKey(iKey, currentCls); ++ if ( enclosingInvariantKeys != null ) ++ for ( InstanceKey obj: enclosingInvariantKeys ) ++ system.newConstraint(x, obj); ++ else ++ system.newConstraint(x, assignOperator, objKey); ++ ++ // If the immediate inclosing class is not a top-level class, we must make EORKs for all enclosing classes up to the top level. ++ // for instance, if we have "D d = c.new D()", and c is of type A$B$C, methods in D may reference variables and functions from ++ // A, B, and C. Therefore we must also make the links from EORK(allocsite of d,enc class B) and EORK(allocsite of d,en class A). ++ // We do this by getting the enclosing class of C and making a link from EORK(d,B) -> EORK(c,B), etc. ++ currentCls = ((JavaClass) currentCls).getEnclosingClass(); ++ while (currentCls != null) { ++ x = new EnclosingObjectReferenceKey(iKey, currentCls); // make EORK(d,B), EORK(d,A), etc. ++ handleEnclosingObject(x, currentCls, objKey); ++ // objKey is the pointer key representing the immediate inner class. ++ // handleEnclosingObject finds x's instance keys and for each one "ik" links x to EORK(ik,currentCls) ++ // thus, for currentCls=B, it will find the allocation site of c and make a link from EORK(d,B) to EORK(c,B) ++ + currentCls = ((JavaClass) currentCls).getEnclosingClass(); +- needIndirection = true; +- } +- +- while (enclosingClass != null) { +- PointerKey x = new EnclosingObjectReferenceKey(iKey, enclosingClass); +- if (needIndirection) { +- handleEnclosingObject(x, currentCls, objKey); +- Trace.println("at " + instruction + ": adding " + iKey + ", " + enclosingClass + " <-- " + objKey + ", " +- + currentCls); +- } else { +- system.newConstraint(x, assignOperator, objKey); +- Trace.println("at " + instruction + ": adding " + iKey + ", " + enclosingClass + " <-- " + objKey); +- } +- +- if (enclosingClass instanceof JavaClass) { +- needIndirection = true; +- enclosingClass = ((JavaClass) enclosingClass).getEnclosingClass(); +- currentCls = ((JavaClass) currentCls).getEnclosingClass(); +- } else { +- break; +- } + } ++ + } + } + } +diff --git a/com.ibm.wala.cast.java/src/com/ibm/wala/cast/java/ipa/callgraph/AstJavaZeroOneContainerCFABuilder.java b/com.ibm.wala.cast.java/src/com/ibm/wala/cast/java/ipa/callgraph/AstJavaZeroOneContainerCFABuilder.java +index cf12e87..d6d9b5e 100644 +--- a/com.ibm.wala.cast.java/src/com/ibm/wala/cast/java/ipa/callgraph/AstJavaZeroOneContainerCFABuilder.java ++++ b/com.ibm.wala.cast.java/src/com/ibm/wala/cast/java/ipa/callgraph/AstJavaZeroOneContainerCFABuilder.java +@@ -62,9 +62,9 @@ public class AstJavaZeroOneContainerCFABuilder extends AstJavaCFABuilder { + setContextInterpreter(contextInterpreter); + + ZeroXInstanceKeys zik = makeInstanceKeys(cha, options, contextInterpreter); +- setInstanceKeys(zik); ++ setInstanceKeys(new JavaScopeMappingInstanceKeys(cha, this, zik)); + +- ContextSelector CCS = makeContainerContextSelector(cha,(ZeroXInstanceKeys) getInstanceKeys()); ++ ContextSelector CCS = makeContainerContextSelector(cha,zik); + DelegatingContextSelector DCS = new DelegatingContextSelector(CCS, contextSelector); + setContextSelector(DCS); + } +diff --git a/com.ibm.wala.cast.java/src/com/ibm/wala/cast/java/ipa/modref/AstJavaModRef.java b/com.ibm.wala.cast.java/src/com/ibm/wala/cast/java/ipa/modref/AstJavaModRef.java +index b02a769..71ea191 100644 +--- a/com.ibm.wala.cast.java/src/com/ibm/wala/cast/java/ipa/modref/AstJavaModRef.java ++++ b/com.ibm.wala.cast.java/src/com/ibm/wala/cast/java/ipa/modref/AstJavaModRef.java +@@ -1,25 +1,55 @@ + package com.ibm.wala.cast.java.ipa.modref; + ++import java.util.ArrayList; + import java.util.Collection; ++import java.util.HashSet; + ++import com.ibm.wala.cast.ipa.callgraph.ScopeMappingInstanceKeys.ScopeMappingInstanceKey; + import com.ibm.wala.cast.ipa.modref.AstModRef; ++import com.ibm.wala.cast.ir.ssa.AstLexicalRead; ++import com.ibm.wala.cast.ir.ssa.AstLexicalAccess.Access; + import com.ibm.wala.cast.java.ssa.AstJavaInstructionVisitor; + import com.ibm.wala.cast.java.ssa.AstJavaInvokeInstruction; + import com.ibm.wala.cast.java.ssa.EnclosingObjectReference; + import com.ibm.wala.ipa.callgraph.CGNode; ++import com.ibm.wala.ipa.callgraph.propagation.InstanceKey; ++import com.ibm.wala.ipa.callgraph.propagation.LocalPointerKey; + import com.ibm.wala.ipa.callgraph.propagation.PointerAnalysis; + import com.ibm.wala.ipa.callgraph.propagation.PointerKey; + import com.ibm.wala.ipa.modref.ExtendedHeapModel; ++import com.ibm.wala.ipa.slicer.HeapExclusions; ++import com.ibm.wala.ssa.SSAInstruction; + + public class AstJavaModRef extends AstModRef { + +- protected static class AstJavaRefVisitor +- extends AstRefVisitor +- implements AstJavaInstructionVisitor +- { +- +- protected AstJavaRefVisitor(CGNode n, Collection result, PointerAnalysis pa, ExtendedHeapModel h) { ++ HashSet lexicalReadMods = new HashSet(); ++ ++ private static class Statement implements PointerKey { ++ public CGNode node; ++ ++ public SSAInstruction inst; ++ ++ public Statement(CGNode node, SSAInstruction inst) { ++ this.node = node; ++ this.inst = inst; ++ } ++ ++ public boolean equals(Object o) { ++ return (o instanceof Statement && ((Statement) o).node == node && ((Statement) o).inst == inst); ++ } ++ ++ public int hashCode() { ++ return node.hashCode() + 19 * inst.hashCode(); ++ } ++ } ++ ++ protected static class AstJavaRefVisitor extends AstRefVisitor implements AstJavaInstructionVisitor { ++ private HashSet lexicalReadMods; ++ ++ protected AstJavaRefVisitor(CGNode n, Collection result, PointerAnalysis pa, ExtendedHeapModel h, ++ HashSet lexicalReadMods) { + super(n, result, pa, h); ++ this.lexicalReadMods = lexicalReadMods; + } + + public void visitJavaInvoke(AstJavaInvokeInstruction instruction) { +@@ -30,22 +60,48 @@ public class AstJavaModRef extends AstModRef { + + } + ++ /** ++ * Finds the instruction the lexical read came from, and make a special pointer key unique to that statement and say ++ * we ref that. Later on, we will have the statement mod this pointer key, thus linking the two statements. ++ * @see AstJavaModRef.getMod(...) ++ */ ++ @Override ++ public void visitAstLexicalRead(AstLexicalRead instruction) { ++ AstLexicalRead alr = instruction; ++ ++ Access[] accesses = alr.getAccesses(); ++ // inner node & alr.getAccesses(); ++ ++ for (int i = 0; i < accesses.length; i++) { ++ final String definer = accesses[i].variableDefiner; ++ final int vn = accesses[i].valueNumber; ++ ++ PointerKey pk = new LocalPointerKey(n, 1); ++ for (InstanceKey ik : pa.getPointsToSet(pk)) { ++ if (ik instanceof ScopeMappingInstanceKey) { ++ // TODO: isn't there only one place in the source this could have come from? why the loop? ++ // find the instruction that the lexical read's value came from ++ CGNode defNode = ((ScopeMappingInstanceKey) ik).getDefiningNode(definer); ++ SSAInstruction defInst = defNode.getDU().getDef(vn); ++ Statement s = new Statement(defNode, defInst); ++ result.add(s); ++ lexicalReadMods.add(s); ++ } ++ } ++ } ++ } + } + + protected RefVisitor makeRefVisitor(CGNode n, Collection result, PointerAnalysis pa, ExtendedHeapModel h) { +- return new AstJavaRefVisitor(n, result, pa, h); ++ return new AstJavaRefVisitor(n, result, pa, h, lexicalReadMods); + } + +- protected static class AstJavaModVisitor +- extends AstModVisitor +- implements AstJavaInstructionVisitor +- { +- ++ protected static class AstJavaModVisitor extends AstModVisitor implements AstJavaInstructionVisitor { ++ + protected AstJavaModVisitor(CGNode n, Collection result, ExtendedHeapModel h, PointerAnalysis pa) { + super(n, result, h, pa); + } + +- + public void visitJavaInvoke(AstJavaInvokeInstruction instruction) { + + } +@@ -54,11 +110,34 @@ public class AstJavaModRef extends AstModRef { + + } + } +- ++ + @Override +- protected ModVisitor makeModVisitor(CGNode n, Collection result, PointerAnalysis pa, ExtendedHeapModel h, boolean ignoreAllocHeapDefs) { ++ protected ModVisitor makeModVisitor(CGNode n, Collection result, PointerAnalysis pa, ExtendedHeapModel h, ++ boolean ignoreAllocHeapDefs) { + return new AstJavaModVisitor(n, result, h, pa); + } + +-} ++ /** ++ * Overridden to provide support for Ast Java lexical reads (in Shrike things like this.val$y -- fields of enclosing ++ * objects). During the ref phase, lexical read instructions find out the instructions defining their values, and make ++ * a pointer key (a "Statement" which is 1-1 mapping to the statement that defined the value) which is their result ++ * set. We also add this Statement to a hashset of "statements that have been referenced by lexical reads". ++ * ++ * Then here, we see if any lexical reads have ref'd us (i.e., we are in the set of "statements referenced by some ++ * lexical read") and if so, add that Statement pointer key to the result set. In that manner, the statement that ++ * defined the value mods the same Statement PointerKey that the lexical read refs. However, for this to work REFS ++ * MUST BE DONE BEFORE MODS! ++ * ++ */ ++ @Override ++ public Collection getMod(CGNode n, ExtendedHeapModel h, PointerAnalysis pa, SSAInstruction s, HeapExclusions hexcl, ++ boolean ignoreAllocHeapDefs) { ++ Collection pks = super.getMod(n, h, pa, s, hexcl, ignoreAllocHeapDefs); ++ ++ Statement statement = new Statement(n, s); ++ if (lexicalReadMods.contains(statement)) ++ pks.add(statement); ++ return pks; ++ } + ++} +diff --git a/com.ibm.wala.cast.java/src/com/ibm/wala/cast/java/ssa/AstJavaNewEnclosingInstruction.java b/com.ibm.wala.cast.java/src/com/ibm/wala/cast/java/ssa/AstJavaNewEnclosingInstruction.java +new file mode 100644 +index 0000000..45718e5 +--- /dev/null ++++ b/com.ibm.wala.cast.java/src/com/ibm/wala/cast/java/ssa/AstJavaNewEnclosingInstruction.java +@@ -0,0 +1,25 @@ ++package com.ibm.wala.cast.java.ssa; ++ ++import com.ibm.wala.classLoader.NewSiteReference; ++import com.ibm.wala.ssa.SSANewInstruction; ++ ++// A new instruction with an explicit outer class, i.e. "Inner inner = outer.new Inner();" ++public class AstJavaNewEnclosingInstruction extends SSANewInstruction { ++ ++ int enclosing; ++ ++ public AstJavaNewEnclosingInstruction(int result, NewSiteReference site, int enclosing) throws IllegalArgumentException { ++ super(result, site); ++ this.enclosing = enclosing; ++ } ++ ++ public int getEnclosing() { ++ return this.enclosing; ++ } ++ ++ public String toString() { ++ return super.toString() + " ENCLOSING v" + enclosing; ++ } ++ ++ ++} +diff --git a/com.ibm.wala.cast.java/src/com/ibm/wala/cast/java/translator/JavaCAst2IRTranslator.java b/com.ibm.wala.cast.java/src/com/ibm/wala/cast/java/translator/JavaCAst2IRTranslator.java +index 9d302ae..774eaaf 100644 +--- a/com.ibm.wala.cast.java/src/com/ibm/wala/cast/java/translator/JavaCAst2IRTranslator.java ++++ b/com.ibm.wala.cast.java/src/com/ibm/wala/cast/java/translator/JavaCAst2IRTranslator.java +@@ -19,6 +19,7 @@ import java.util.Iterator; + import com.ibm.wala.cast.ir.translator.AstTranslator; + import com.ibm.wala.cast.java.loader.JavaSourceLoaderImpl; + import com.ibm.wala.cast.java.ssa.AstJavaInvokeInstruction; ++import com.ibm.wala.cast.java.ssa.AstJavaNewEnclosingInstruction; + import com.ibm.wala.cast.java.ssa.EnclosingObjectReference; + import com.ibm.wala.cast.loader.AstMethod.DebuggingInformation; + import com.ibm.wala.cast.loader.AstMethod.LexicalInformation; +@@ -156,11 +157,14 @@ public class JavaCAst2IRTranslator extends AstTranslator { + NewSiteReference site = + NewSiteReference.make(context.cfg().getCurrentInstruction(), typeRef); + +- context.cfg().addInstruction( +- (arguments == null)? +- SSAInstructionFactory.NewInstruction(result, site): +- new SSANewInstruction(result, site, arguments)); +- ++ if ( newNode.getKind() == CAstNode.NEW_ENCLOSING ) { ++ context.cfg().addInstruction ( new AstJavaNewEnclosingInstruction(result, site, arguments[0])); ++ } else { ++ context.cfg().addInstruction( ++ (arguments == null)? ++ SSAInstructionFactory.NewInstruction(result, site): ++ new SSANewInstruction(result, site, arguments)); ++ } + processExceptions(newNode, context); + } + +diff --git a/com.ibm.wala.cast.java/src/com/ibm/wala/cast/java/translator/polyglot/PolyglotJava2CAstTranslator.java b/com.ibm.wala.cast.java/src/com/ibm/wala/cast/java/translator/polyglot/PolyglotJava2CAstTranslator.java +index f9f1222..17910ce 100644 +--- a/com.ibm.wala.cast.java/src/com/ibm/wala/cast/java/translator/polyglot/PolyglotJava2CAstTranslator.java ++++ b/com.ibm.wala.cast.java/src/com/ibm/wala/cast/java/translator/polyglot/PolyglotJava2CAstTranslator.java +@@ -746,7 +746,16 @@ public class PolyglotJava2CAstTranslator implements TranslatorToCAst { + String tmpName = "ctor temp"; // this name is an illegal Java + // identifier + +- CAstNode newNode = makeNode(wc, fFactory, n, CAstNode.NEW, fFactory.makeConstant(newTypeRef)); ++ // new nodes with an explicit enclosing argument, e.g. "outer.new Inner()". They are mostly treated the same, except in JavaCAst2IRTranslator.doNewObject ++ CAstNode newNode; ++ Expr enclosing = n.qualifier(); ++ if ( enclosing != null ) { ++ CAstNode encNode = walkNodes(enclosing, wc); ++ newNode = makeNode(wc, fFactory, n, CAstNode.NEW_ENCLOSING, fFactory.makeConstant(newTypeRef), encNode); ++ } ++ else ++ newNode = makeNode(wc, fFactory, n, CAstNode.NEW, fFactory.makeConstant(newTypeRef)); ++ // end enclosing new stuff + + if (n.body() != null) + wc.addScopedEntity(newNode, anonClass); +diff --git a/com.ibm.wala.cast.js/META-INF/MANIFEST.MF b/com.ibm.wala.cast.js/META-INF/MANIFEST.MF +new file mode 100644 +index 0000000..f23aeaf +--- /dev/null ++++ b/com.ibm.wala.cast.js/META-INF/MANIFEST.MF +@@ -0,0 +1,91 @@ ++Manifest-Version: 1.0 ++Bundle-ManifestVersion: 2 ++Bundle-Name: Javascript Source WALA Front End ++Bundle-SymbolicName: com.ibm.wala.cast.js ++Bundle-Version: 1.0.0 ++Bundle-Activator: com.ibm.wala.cast.js.JavaScriptPlugin ++Bundle-Vendor: rfuhrer@watson.ibm.com ++Require-Bundle: com.ibm.wala.cast;visibility:=reexport, ++ com.ibm.wala.core;visibility:=reexport ++Eclipse-LazyStart: true ++Export-Package: com.ibm.wala.cast.js, ++ com.ibm.wala.cast.js.analysis.typeInference, ++ com.ibm.wala.cast.js.cfg, ++ com.ibm.wala.cast.js.client, ++ com.ibm.wala.cast.js.client.impl, ++ com.ibm.wala.cast.js.ipa.callgraph, ++ com.ibm.wala.cast.js.ipa.summaries, ++ com.ibm.wala.cast.js.loader, ++ com.ibm.wala.cast.js.ssa, ++ com.ibm.wala.cast.js.translator, ++ com.ibm.wala.cast.js.types, ++ com.ibm.wala.cast.js.util, ++ java_cup.runtime, ++ org.apache.bcel, ++ org.apache.bcel.classfile, ++ org.apache.bcel.generic, ++ org.apache.bcel.util, ++ org.apache.bcel.verifier, ++ org.apache.bcel.verifier.exc, ++ org.apache.bcel.verifier.statics, ++ org.apache.bcel.verifier.structurals, ++ org.apache.regexp, ++ org.apache.xalan, ++ org.apache.xalan.client, ++ org.apache.xalan.extensions, ++ org.apache.xalan.lib, ++ org.apache.xalan.lib.sql, ++ org.apache.xalan.processor, ++ org.apache.xalan.res, ++ org.apache.xalan.serialize, ++ org.apache.xalan.templates, ++ org.apache.xalan.trace, ++ org.apache.xalan.transformer, ++ org.apache.xalan.xslt, ++ org.apache.xalan.xsltc, ++ org.apache.xalan.xsltc.cmdline, ++ org.apache.xalan.xsltc.cmdline.getopt, ++ org.apache.xalan.xsltc.compiler, ++ org.apache.xalan.xsltc.compiler.util, ++ org.apache.xalan.xsltc.dom, ++ org.apache.xalan.xsltc.runtime, ++ org.apache.xalan.xsltc.runtime.output, ++ org.apache.xalan.xsltc.trax, ++ org.apache.xalan.xsltc.util, ++ org.apache.xml.dtm, ++ org.apache.xml.dtm.ref, ++ org.apache.xml.dtm.ref.dom2dtm, ++ org.apache.xml.dtm.ref.sax2dtm, ++ org.apache.xml.res, ++ org.apache.xml.utils, ++ org.apache.xml.utils.res, ++ org.apache.xpath, ++ org.apache.xpath.axes, ++ org.apache.xpath.compiler, ++ org.apache.xpath.domapi, ++ org.apache.xpath.functions, ++ org.apache.xpath.jaxp, ++ org.apache.xpath.objects, ++ org.apache.xpath.operations, ++ org.apache.xpath.patterns, ++ org.apache.xpath.res, ++ org.mozilla.classfile, ++ org.mozilla.javascript, ++ org.mozilla.javascript.continuations, ++ org.mozilla.javascript.debug, ++ org.mozilla.javascript.jdk11, ++ org.mozilla.javascript.jdk13, ++ org.mozilla.javascript.optimizer, ++ org.mozilla.javascript.regexp, ++ org.mozilla.javascript.serialize, ++ org.mozilla.javascript.tools, ++ org.mozilla.javascript.tools.debugger, ++ org.mozilla.javascript.tools.debugger.downloaded, ++ org.mozilla.javascript.tools.idswitch, ++ org.mozilla.javascript.tools.jsc, ++ org.mozilla.javascript.tools.shell, ++ org.mozilla.javascript.xml, ++ org.mozilla.javascript.xmlimpl ++Bundle-ClassPath: ., ++ lib/xalan.jar, ++ lib/js.jar +diff --git a/com.ibm.wala.cast.js/build.properties b/com.ibm.wala.cast.js/build.properties +index 36e03bf..999ffb1 100644 +--- a/com.ibm.wala.cast.js/build.properties ++++ b/com.ibm.wala.cast.js/build.properties +@@ -1,5 +1,6 @@ + output.js.jar = bin/ +-bin.includes = plugin.xml,\ ++bin.includes = META-INF/,\ ++ .,\ + lib/js.jar,\ + lib/xalan.jar,\ + . +diff --git a/com.ibm.wala.cast.js/plugin.xml b/com.ibm.wala.cast.js/plugin.xml +deleted file mode 100644 +index 7d47caf..0000000 +--- a/com.ibm.wala.cast.js/plugin.xml ++++ /dev/null +@@ -1,24 +0,0 @@ +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +diff --git a/com.ibm.wala.cast/source/java/com/ibm/wala/cast/ipa/callgraph/ScopeMappingInstanceKeys.java b/com.ibm.wala.cast/source/java/com/ibm/wala/cast/ipa/callgraph/ScopeMappingInstanceKeys.java +index 381a8cf..711617c 100644 +--- a/com.ibm.wala.cast/source/java/com/ibm/wala/cast/ipa/callgraph/ScopeMappingInstanceKeys.java ++++ b/com.ibm.wala.cast/source/java/com/ibm/wala/cast/ipa/callgraph/ScopeMappingInstanceKeys.java +@@ -128,7 +128,7 @@ abstract public class ScopeMappingInstanceKeys implements InstanceKeyFactory { + return base.getConcreteType(); + } + +- CGNode getDefiningNode(String definer) { ++ public CGNode getDefiningNode(String definer) { + return map.getDefiningNode(definer); + } + +diff --git a/com.ibm.wala.cast/source/java/com/ibm/wala/cast/ir/translator/AstTranslator.java b/com.ibm.wala.cast/source/java/com/ibm/wala/cast/ir/translator/AstTranslator.java +index 1c41365..ec8cd1e 100644 +--- a/com.ibm.wala.cast/source/java/com/ibm/wala/cast/ir/translator/AstTranslator.java ++++ b/com.ibm.wala.cast/source/java/com/ibm/wala/cast/ir/translator/AstTranslator.java +@@ -2610,8 +2610,8 @@ public abstract class AstTranslator extends CAstVisitor + int result = getValue(n); + CAstNode l = n.getChild(1); + CAstNode r = n.getChild(2); +- Assertions._assert(getValue(r) != -1, CAstPrinter.print(n)); +- Assertions._assert(getValue(l) != -1, CAstPrinter.print(n)); ++// Assertions._assert(getValue(r) != -1, CAstPrinter.print(n)); ++// Assertions._assert(getValue(l) != -1, CAstPrinter.print(n)); + + boolean mayBeInteger = handleBinaryOpThrow(n, n.getChild(0), context); + +diff --git a/com.ibm.wala.cast/source/java/com/ibm/wala/cast/tree/CAstNode.java b/com.ibm.wala.cast/source/java/com/ibm/wala/cast/tree/CAstNode.java +index 18bf26f..b420421 100644 +--- a/com.ibm.wala.cast/source/java/com/ibm/wala/cast/tree/CAstNode.java ++++ b/com.ibm.wala.cast/source/java/com/ibm/wala/cast/tree/CAstNode.java +@@ -155,6 +155,9 @@ public interface CAstNode { + public static final int TYPE_LITERAL_EXPR = 127; + public static final int IS_DEFINED_EXPR = 128; + ++ // new nodes with an explicit enclosing argument, e.g. "outer.new Inner()". They are mostly treated the same, except in JavaCAst2IRTranslator.doNewObject ++ public static final int NEW_ENCLOSING = 129; ++ + // explicit lexical scopes + public static final int LOCAL_SCOPE = 200; + +diff --git a/com.ibm.wala.cast/source/java/com/ibm/wala/cast/tree/visit/CAstVisitor.java b/com.ibm.wala.cast/source/java/com/ibm/wala/cast/tree/visit/CAstVisitor.java +index 44f7055..e3ad94f 100644 +--- a/com.ibm.wala.cast/source/java/com/ibm/wala/cast/tree/visit/CAstVisitor.java ++++ b/com.ibm.wala.cast/source/java/com/ibm/wala/cast/tree/visit/CAstVisitor.java +@@ -554,6 +554,7 @@ public abstract class CAstVisitor { + break; + } + ++ case CAstNode.NEW_ENCLOSING: + case CAstNode.NEW: { + if (visitor.visitNew(n, context, visitor)) + break; +diff --git a/com.ibm.wala.cast/source/java/com/ibm/wala/cast/util/CAstPrinter.java b/com.ibm.wala.cast/source/java/com/ibm/wala/cast/util/CAstPrinter.java +index 05ef170..ef226b7 100644 +--- a/com.ibm.wala.cast/source/java/com/ibm/wala/cast/util/CAstPrinter.java ++++ b/com.ibm.wala.cast/source/java/com/ibm/wala/cast/util/CAstPrinter.java +@@ -71,6 +71,7 @@ public class CAstPrinter { + case CAstNode.IF_EXPR: return "IF_EXPR"; + case CAstNode.ANDOR_EXPR: return "ANDOR_EXPR"; + case CAstNode.NEW: return "NEW"; ++ case CAstNode.NEW_ENCLOSING: return "NEW_ENCLOSING"; + case CAstNode.OBJECT_LITERAL: return "LITERAL"; + case CAstNode.VAR: return "VAR"; + case CAstNode.OBJECT_REF: return "OBJECT_REF"; +diff --git a/com.ibm.wala.core/src/com/ibm/wala/ipa/callgraph/propagation/HeapModel.java b/com.ibm.wala.core/src/com/ibm/wala/ipa/callgraph/propagation/HeapModel.java +index 324a7b7..6a4ee23 100644 +--- a/com.ibm.wala.core/src/com/ibm/wala/ipa/callgraph/propagation/HeapModel.java ++++ b/com.ibm.wala.core/src/com/ibm/wala/ipa/callgraph/propagation/HeapModel.java +@@ -13,6 +13,7 @@ package com.ibm.wala.ipa.callgraph.propagation; + import java.util.Iterator; + + import com.ibm.wala.ipa.cha.IClassHierarchy; ++import com.ibm.wala.ipa.modref.ModRef; + + + /** +@@ -32,5 +33,4 @@ public interface HeapModel extends InstanceKeyFactory, PointerKeyFactory { + * @return the governing class hierarchy for this heap model + */ + IClassHierarchy getClassHierarchy(); +- + } +diff --git a/com.ibm.wala.core/src/com/ibm/wala/ipa/modref/ModRef.java b/com.ibm.wala.core/src/com/ibm/wala/ipa/modref/ModRef.java +index e19a6ce..1f6f533 100644 +--- a/com.ibm.wala.core/src/com/ibm/wala/ipa/modref/ModRef.java ++++ b/com.ibm.wala.core/src/com/ibm/wala/ipa/modref/ModRef.java +@@ -191,13 +191,13 @@ public class ModRef { + } + + protected static class RefVisitor extends SSAInstruction.Visitor { +- private final CGNode n; ++ protected final CGNode n; + +- private final Collection result; ++ protected final Collection result; + +- private final PointerAnalysis pa; ++ protected final PointerAnalysis pa; + +- private final ExtendedHeapModel h; ++ protected final ExtendedHeapModel h; + + protected RefVisitor(CGNode n, Collection result, PointerAnalysis pa, ExtendedHeapModel h) { + this.n = n; +@@ -239,15 +239,15 @@ public class ModRef { + } + + protected static class ModVisitor extends SSAInstruction.Visitor { +- private final CGNode n; ++ protected final CGNode n; + +- private final Collection result; ++ protected final Collection result; + +- private final ExtendedHeapModel h; ++ protected final ExtendedHeapModel h; + +- private final PointerAnalysis pa; ++ protected final PointerAnalysis pa; + +- private final boolean ignoreAllocHeapDefs; ++ protected final boolean ignoreAllocHeapDefs; + + protected ModVisitor(CGNode n, Collection result, ExtendedHeapModel h, PointerAnalysis pa, boolean ignoreAllocHeapDefs) { + this.n = n; -- 2.11.4.GIT