Revert "refactor context selectors: extract delegation into ComposedContextSelector"
This reverts commit 7ff1219c5baed388a82d14fcf81d2b1f456c4e95. That commit broke a dojo test, and I'm not sure why. git-svn-id: https://wala.svn.sourceforge.net/svnroot/wala/trunk@4491 f5eafffb-2e1d-0410-98e4-8ec43c5233c4
This commit is contained in:
parent
59d602e9b7
commit
92d8dc1e3d
|
@ -19,7 +19,6 @@ import com.ibm.wala.cast.js.test.Util;
|
|||
import com.ibm.wala.cast.js.translator.CAstRhinoTranslatorFactory;
|
||||
import com.ibm.wala.ipa.callgraph.CallGraph;
|
||||
import com.ibm.wala.ipa.callgraph.CallGraphBuilderCancelException;
|
||||
import com.ibm.wala.ipa.callgraph.ComposedContextSelector;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.PointerAnalysis;
|
||||
import com.ibm.wala.ipa.cha.ClassHierarchyException;
|
||||
import com.ibm.wala.util.ProgressMaster;
|
||||
|
@ -83,9 +82,8 @@ public class HTMLCGBuilder {
|
|||
JSCFABuilder builder = null;
|
||||
try {
|
||||
builder = Util.makeHTMLCGBuilder(url);
|
||||
builder.setContextSelector(new ComposedContextSelector(builder
|
||||
.getContextSelector(), new ForInContextSelector(2),
|
||||
new ForInContextSelector(3)));
|
||||
builder.setContextSelector(new ForInContextSelector(2, builder.getContextSelector()));
|
||||
builder.setContextSelector(new ForInContextSelector(3, builder.getContextSelector()));
|
||||
ProgressMaster master = ProgressMaster.make(new NullProgressMonitor());
|
||||
if (timeout > 0) {
|
||||
master.setMillisPerWorkItem(timeout * 1000);
|
||||
|
|
|
@ -11,7 +11,7 @@ import com.ibm.wala.cast.js.html.JSSourceExtractor;
|
|||
import com.ibm.wala.cast.js.ipa.callgraph.ForInContextSelector;
|
||||
import com.ibm.wala.cast.js.ipa.callgraph.JSCFABuilder;
|
||||
import com.ibm.wala.ipa.callgraph.CallGraph;
|
||||
import com.ibm.wala.ipa.callgraph.ComposedContextSelector;
|
||||
import com.ibm.wala.ipa.callgraph.ContextSelector;
|
||||
import com.ibm.wala.util.CancelException;
|
||||
|
||||
public abstract class TestForInLoopHack extends TestJSCallGraphShape {
|
||||
|
@ -161,7 +161,8 @@ public abstract class TestForInLoopHack extends TestJSCallGraphShape {
|
|||
*/
|
||||
|
||||
private void addHackedForInLoopSensitivity(JSCFABuilder builder) {
|
||||
builder.setContextSelector(new ComposedContextSelector(builder.getContextSelector(), new ForInContextSelector()));
|
||||
final ContextSelector orig = builder.getContextSelector();
|
||||
builder.setContextSelector(new ForInContextSelector(orig));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -27,7 +27,6 @@ import com.ibm.wala.ipa.callgraph.Context;
|
|||
import com.ibm.wala.ipa.callgraph.ContextItem;
|
||||
import com.ibm.wala.ipa.callgraph.ContextKey;
|
||||
import com.ibm.wala.ipa.callgraph.ContextSelector;
|
||||
import com.ibm.wala.ipa.callgraph.impl.ContextInsensitiveSelector;
|
||||
import com.ibm.wala.ipa.callgraph.impl.Everywhere;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.ConcreteTypeKey;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.ConstantKey;
|
||||
|
@ -46,7 +45,6 @@ import com.ibm.wala.ssa.SSAOptions;
|
|||
import com.ibm.wala.types.MethodReference;
|
||||
import com.ibm.wala.util.collections.HashMapFactory;
|
||||
import com.ibm.wala.util.collections.Iterator2Iterable;
|
||||
import com.ibm.wala.util.intset.EmptyIntSet;
|
||||
import com.ibm.wala.util.intset.IntSet;
|
||||
import com.ibm.wala.util.intset.IntSetUtil;
|
||||
import com.ibm.wala.util.intset.MutableIntSet;
|
||||
|
@ -105,8 +103,9 @@ public class ForInContextSelector implements ContextSelector {
|
|||
public static boolean DEPENDENT_THRU_READS = true;
|
||||
|
||||
public static class SelectiveCPAContext implements Context {
|
||||
|
||||
private final Map<ContextKey, InstanceKey> parameterObjs;
|
||||
protected final Context base;
|
||||
|
||||
private final Map<ContextKey, InstanceKey> parameterObjs;
|
||||
|
||||
private final int hashCode;
|
||||
|
||||
|
@ -120,20 +119,21 @@ public class ForInContextSelector implements ContextSelector {
|
|||
return result;
|
||||
}
|
||||
|
||||
public SelectiveCPAContext(InstanceKey[] x) {
|
||||
this(makeMap(x));
|
||||
public SelectiveCPAContext(Context base, InstanceKey[] x) {
|
||||
this(base, makeMap(x));
|
||||
}
|
||||
|
||||
public SelectiveCPAContext(Map<ContextKey, InstanceKey> parameterObjs) {
|
||||
public SelectiveCPAContext(Context base, Map<ContextKey, InstanceKey> parameterObjs) {
|
||||
this.base = base;
|
||||
this.parameterObjs = parameterObjs;
|
||||
hashCode = parameterObjs.hashCode();
|
||||
hashCode = base.hashCode() ^ parameterObjs.hashCode();
|
||||
}
|
||||
|
||||
public ContextItem get(ContextKey name) {
|
||||
if (parameterObjs.containsKey(name)) {
|
||||
return new FilteredPointerKey.SingleInstanceFilter(parameterObjs.get(name));
|
||||
} else {
|
||||
return null;
|
||||
return base.get(name);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -145,6 +145,7 @@ public class ForInContextSelector implements ContextSelector {
|
|||
public boolean equals(Object other) {
|
||||
return other != null &&
|
||||
getClass().equals(other.getClass()) &&
|
||||
base.equals(((SelectiveCPAContext)other).base) &&
|
||||
parameterObjs.equals(((SelectiveCPAContext)other).parameterObjs);
|
||||
}
|
||||
|
||||
|
@ -153,8 +154,8 @@ public class ForInContextSelector implements ContextSelector {
|
|||
|
||||
public class ForInContext extends SelectiveCPAContext {
|
||||
|
||||
ForInContext(InstanceKey obj) {
|
||||
super(Collections.singletonMap(ContextKey.PARAMETERS[index], obj));
|
||||
ForInContext(Context base, InstanceKey obj) {
|
||||
super(base, Collections.singletonMap(ContextKey.PARAMETERS[index], obj));
|
||||
}
|
||||
|
||||
public ContextItem get(ContextKey key) {
|
||||
|
@ -169,11 +170,12 @@ public class ForInContextSelector implements ContextSelector {
|
|||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "for in hack filter for " + get(ContextKey.PARAMETERS[index]);
|
||||
return "for in hack filter for " + get(ContextKey.PARAMETERS[index]) + " over " + this.base;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private final ContextSelector base;
|
||||
private final ContextSelector oneLevel;
|
||||
private final int index;
|
||||
|
||||
|
@ -210,13 +212,14 @@ public class ForInContextSelector implements ContextSelector {
|
|||
return dependentParameters;
|
||||
}
|
||||
|
||||
public ForInContextSelector() {
|
||||
this(2);
|
||||
public ForInContextSelector(ContextSelector base) {
|
||||
this(2, base);
|
||||
}
|
||||
|
||||
public ForInContextSelector(int index) {
|
||||
public ForInContextSelector(int index, ContextSelector base) {
|
||||
this.index = index;
|
||||
this.oneLevel = new OneLevelSiteContextSelector(new ContextInsensitiveSelector());
|
||||
this.base = base;
|
||||
this.oneLevel = new OneLevelSiteContextSelector(base);
|
||||
}
|
||||
|
||||
private final HashMap<MethodReference, Boolean> forInOnFirstArg_cache = HashMapFactory.make();
|
||||
|
@ -315,28 +318,29 @@ public class ForInContextSelector implements ContextSelector {
|
|||
}
|
||||
|
||||
public Context getCalleeTarget(CGNode caller, CallSiteReference site, IMethod callee, final InstanceKey[] receiver) {
|
||||
Context baseContext = base.getCalleeTarget(caller, site, callee, receiver);
|
||||
String calleeFullName = callee.getDeclaringClass().getName().toString();
|
||||
String calleeShortName = calleeFullName.substring(calleeFullName.lastIndexOf('/')+1);
|
||||
if(USE_NAME_TO_SELECT_CONTEXT) {
|
||||
if(calleeShortName.contains(HACK_METHOD_STR) && receiver.length > index) {
|
||||
// we assume that the argument is only used as a property name, so we can do ToString
|
||||
return new ForInContext(simulateToString(caller.getClassHierarchy(), receiver[index]));
|
||||
return new ForInContext(baseContext, simulateToString(caller.getClassHierarchy(), receiver[index]));
|
||||
}
|
||||
} else if(receiver.length > index) {
|
||||
Frequency f = usesFirstArgAsPropertyName(callee);
|
||||
if(f == Frequency.ALWAYS) {
|
||||
return new ForInContext(simulateToString(caller.getClassHierarchy(), receiver[index]));
|
||||
return new ForInContext(baseContext, simulateToString(caller.getClassHierarchy(), receiver[index]));
|
||||
} else if(f == Frequency.SOMETIMES) {
|
||||
if(receiver[index] == null) {
|
||||
IClass undef = caller.getClassHierarchy().lookupClass(JavaScriptTypes.Undefined);
|
||||
return new ForInContext(new ConcreteTypeKey(undef));
|
||||
return new ForInContext(baseContext, new ConcreteTypeKey(undef));
|
||||
} else {
|
||||
return new ForInContext(receiver[index]);
|
||||
return new ForInContext(baseContext, receiver[index]);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (USE_CPA_IN_BODIES && FORIN_MARKER.equals(caller.getContext().get(FORIN_KEY))) {
|
||||
return new SelectiveCPAContext(receiver);
|
||||
return new SelectiveCPAContext(baseContext, receiver);
|
||||
} else if (USE_1LEVEL_IN_BODIES && FORIN_MARKER.equals(caller.getContext().get(FORIN_KEY))) {
|
||||
if (! identifyDependentParameters(caller, site).isEmpty()) {
|
||||
// RECURSION CHECK: only add one level of caller-site contexts if the caller and callee methods are distinct
|
||||
|
@ -344,10 +348,10 @@ public class ForInContextSelector implements ContextSelector {
|
|||
return oneLevel.getCalleeTarget(caller, site, callee, receiver);
|
||||
}
|
||||
} else {
|
||||
return null;
|
||||
return baseContext;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
return baseContext;
|
||||
}
|
||||
|
||||
public IntSet getRelevantParameters(CGNode caller, CallSiteReference site) {
|
||||
|
@ -355,9 +359,9 @@ public class ForInContextSelector implements ContextSelector {
|
|||
// what about base.getRelevantParameters() here?
|
||||
return identifyDependentParameters(caller, site);
|
||||
} else if (caller.getIR().getCalls(site)[0].getNumberOfUses() > index) {
|
||||
return IntSetUtil.make(new int[]{index});
|
||||
return IntSetUtil.make(new int[]{index}).union(base.getRelevantParameters(caller, site));
|
||||
} else {
|
||||
return EmptyIntSet.instance;
|
||||
return base.getRelevantParameters(caller, site);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -10,15 +10,11 @@
|
|||
*****************************************************************************/
|
||||
package com.ibm.wala.cast.js.ipa.callgraph;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
|
||||
import com.ibm.wala.cast.ipa.callgraph.LexicalScopingResolverContexts;
|
||||
import com.ibm.wala.cast.ipa.callgraph.ScopeMappingKeysContextSelector;
|
||||
import com.ibm.wala.cast.ir.translator.AstTranslator;
|
||||
import com.ibm.wala.ipa.callgraph.AnalysisCache;
|
||||
import com.ibm.wala.ipa.callgraph.AnalysisScope;
|
||||
import com.ibm.wala.ipa.callgraph.ComposedContextSelector;
|
||||
import com.ibm.wala.ipa.callgraph.ContextSelector;
|
||||
import com.ibm.wala.ipa.callgraph.MethodTargetSelector;
|
||||
import com.ibm.wala.ipa.callgraph.impl.ContextInsensitiveSelector;
|
||||
|
@ -42,41 +38,13 @@ public class JSZeroOrOneXCFABuilder extends JSCFABuilder {
|
|||
ContextSelector appContextSelector, SSAContextInterpreter appContextInterpreter, int instancePolicy, boolean doOneCFA) {
|
||||
super(cha, options, cache);
|
||||
|
||||
SSAContextInterpreter contextInterpreter = setupSSAContextInterpreter(cha, options, cache, appContextInterpreter);
|
||||
|
||||
setupMethodTargetSelector(cha, options);
|
||||
|
||||
setupContextSelector(options, appContextSelector, doOneCFA);
|
||||
|
||||
setInstanceKeys(new JavaScriptScopeMappingInstanceKeys(cha, this, new JavaScriptConstructorInstanceKeys(new ZeroXInstanceKeys(
|
||||
options, cha, contextInterpreter, instancePolicy))));
|
||||
}
|
||||
|
||||
private void setupContextSelector(JSAnalysisOptions options, ContextSelector appContextSelector, boolean doOneCFA) {
|
||||
Collection<ContextSelector> selectors = new ArrayList<ContextSelector>();
|
||||
ContextSelector def = new ContextInsensitiveSelector();
|
||||
ContextSelector contextSelector = appContextSelector == null ? def : new DelegatingContextSelector(appContextSelector, def);
|
||||
selectors.add(contextSelector);
|
||||
// if (!AstTranslator.NEW_LEXICAL) {
|
||||
selectors.add(new ScopeMappingKeysContextSelector());
|
||||
// }
|
||||
selectors.add(new JavaScriptConstructorContextSelector());
|
||||
if (USE_OBJECT_SENSITIVITY) {
|
||||
selectors.add(new ObjectSensitivityContextSelector());
|
||||
}
|
||||
SSAContextInterpreter contextInterpreter = makeDefaultContextInterpreters(appContextInterpreter, options, cha);
|
||||
if (options.handleCallApply()) {
|
||||
selectors.add(new JavaScriptFunctionApplyContextSelector());
|
||||
contextInterpreter = new DelegatingSSAContextInterpreter(new JavaScriptFunctionApplyContextInterpreter(options, cache),
|
||||
contextInterpreter);
|
||||
}
|
||||
if (!AstTranslator.NEW_LEXICAL) {
|
||||
selectors.add(new LexicalScopingResolverContexts(this));
|
||||
}
|
||||
if (doOneCFA) {
|
||||
selectors.add(new nCFAContextSelector(1, new ContextInsensitiveSelector()));
|
||||
}
|
||||
setContextSelector(new ComposedContextSelector(selectors));
|
||||
}
|
||||
setContextInterpreter(contextInterpreter);
|
||||
|
||||
private void setupMethodTargetSelector(IClassHierarchy cha, JSAnalysisOptions options) {
|
||||
MethodTargetSelector targetSelector = new JavaScriptConstructTargetSelector(cha, options
|
||||
.getMethodTargetSelector());
|
||||
if (options.handleCallApply()) {
|
||||
|
@ -86,17 +54,29 @@ public class JSZeroOrOneXCFABuilder extends JSCFABuilder {
|
|||
targetSelector = new LoadFileTargetSelector(targetSelector, this);
|
||||
}
|
||||
options.setSelector(targetSelector);
|
||||
}
|
||||
|
||||
private SSAContextInterpreter setupSSAContextInterpreter(IClassHierarchy cha, JSAnalysisOptions options, AnalysisCache cache,
|
||||
SSAContextInterpreter appContextInterpreter) {
|
||||
SSAContextInterpreter contextInterpreter = makeDefaultContextInterpreters(appContextInterpreter, options, cha);
|
||||
if (options.handleCallApply()) {
|
||||
contextInterpreter = new DelegatingSSAContextInterpreter(new JavaScriptFunctionApplyContextInterpreter(options, cache),
|
||||
contextInterpreter);
|
||||
ContextSelector def = new ContextInsensitiveSelector();
|
||||
ContextSelector contextSelector = appContextSelector == null ? def : new DelegatingContextSelector(appContextSelector, def);
|
||||
// if (!AstTranslator.NEW_LEXICAL) {
|
||||
contextSelector = new ScopeMappingKeysContextSelector(contextSelector);
|
||||
// }
|
||||
contextSelector = new JavaScriptConstructorContextSelector(contextSelector);
|
||||
if (USE_OBJECT_SENSITIVITY) {
|
||||
contextSelector = new ObjectSensitivityContextSelector(contextSelector);
|
||||
}
|
||||
setContextInterpreter(contextInterpreter);
|
||||
return contextInterpreter;
|
||||
if (options.handleCallApply()) {
|
||||
contextSelector = new JavaScriptFunctionApplyContextSelector(contextSelector);
|
||||
}
|
||||
if (!AstTranslator.NEW_LEXICAL) {
|
||||
contextSelector = new LexicalScopingResolverContexts(this, contextSelector);
|
||||
}
|
||||
if (doOneCFA) {
|
||||
contextSelector = new nCFAContextSelector(1, contextSelector);
|
||||
}
|
||||
setContextSelector(contextSelector);
|
||||
|
||||
setInstanceKeys(new JavaScriptScopeMappingInstanceKeys(cha, this, new JavaScriptConstructorInstanceKeys(new ZeroXInstanceKeys(
|
||||
options, cha, contextInterpreter, instancePolicy))));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -10,25 +10,32 @@ 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.DelegatingContext;
|
||||
import com.ibm.wala.ipa.callgraph.impl.ContextInsensitiveSelector;
|
||||
import com.ibm.wala.ipa.callgraph.impl.Everywhere;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.InstanceKey;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.cfa.CallerSiteContext;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.cfa.OneLevelSiteContextSelector;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.cfa.nCFAContextSelector;
|
||||
import com.ibm.wala.util.intset.EmptyIntSet;
|
||||
import com.ibm.wala.util.intset.IntSet;
|
||||
|
||||
public class JavaScriptConstructorContextSelector implements ContextSelector {
|
||||
private nCFAContextSelector oneLevelCallStrings;
|
||||
private OneLevelSiteContextSelector oneLevelCallerSite;
|
||||
private final ContextSelector base;
|
||||
|
||||
public JavaScriptConstructorContextSelector() {
|
||||
final ContextInsensitiveSelector dummyBase = new ContextInsensitiveSelector();
|
||||
this.oneLevelCallStrings = new nCFAContextSelector(1, dummyBase);
|
||||
this.oneLevelCallerSite = new OneLevelSiteContextSelector(dummyBase);
|
||||
/**
|
||||
* for generating contexts with one-level of call strings, to match standard
|
||||
* Andersen's heap abstraction
|
||||
*/
|
||||
private final nCFAContextSelector oneLevelCallStrings;
|
||||
|
||||
private final OneLevelSiteContextSelector oneLevelCallerSite;
|
||||
|
||||
public JavaScriptConstructorContextSelector(ContextSelector base) {
|
||||
this.base = base;
|
||||
this.oneLevelCallStrings = new nCFAContextSelector(1, base);
|
||||
this.oneLevelCallerSite = new OneLevelSiteContextSelector(base);
|
||||
}
|
||||
|
||||
public IntSet getRelevantParameters(CGNode caller, CallSiteReference site) {
|
||||
return EmptyIntSet.instance;
|
||||
return base.getRelevantParameters(caller, site);
|
||||
}
|
||||
|
||||
public Context getCalleeTarget(final CGNode caller, CallSiteReference site, IMethod callee, InstanceKey[] receiver) {
|
||||
|
@ -38,8 +45,7 @@ public class JavaScriptConstructorContextSelector implements ContextSelector {
|
|||
if (!AstTranslator.NEW_LEXICAL && callerContext instanceof ScopeMappingContext) {
|
||||
return new DelegatingContext(callerContext, oneLevelCallStringContext);
|
||||
} else if (AstTranslator.NEW_LEXICAL && LexicalScopingResolverContexts.hasExposedUses(caller, site)) {
|
||||
// use a caller-site context, to enable lexical scoping lookups (via
|
||||
// caller CGNode)
|
||||
// use a caller-site context, to enable lexical scoping lookups (via caller CGNode)
|
||||
return oneLevelCallerSite.getCalleeTarget(caller, site, callee, receiver);
|
||||
} else {
|
||||
// use at least one-level of call-string sensitivity for constructors
|
||||
|
@ -47,7 +53,7 @@ public class JavaScriptConstructorContextSelector implements ContextSelector {
|
|||
return oneLevelCallStringContext;
|
||||
}
|
||||
} else {
|
||||
return null;
|
||||
return base.getCalleeTarget(caller, site, callee, receiver);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -10,12 +10,9 @@ import com.ibm.wala.ipa.callgraph.Context;
|
|||
import com.ibm.wala.ipa.callgraph.ContextItem;
|
||||
import com.ibm.wala.ipa.callgraph.ContextKey;
|
||||
import com.ibm.wala.ipa.callgraph.ContextSelector;
|
||||
import com.ibm.wala.ipa.callgraph.DelegatingContext;
|
||||
import com.ibm.wala.ipa.callgraph.impl.ContextInsensitiveSelector;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.InstanceKey;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.cfa.nCFAContextSelector;
|
||||
import com.ibm.wala.types.TypeName;
|
||||
import com.ibm.wala.util.intset.EmptyIntSet;
|
||||
import com.ibm.wala.util.intset.IntSet;
|
||||
import com.ibm.wala.util.intset.IntSetUtil;
|
||||
|
||||
|
@ -26,11 +23,8 @@ import com.ibm.wala.util.intset.IntSetUtil;
|
|||
* Function.prototype.apply() docs</a>
|
||||
*/
|
||||
public class JavaScriptFunctionApplyContextSelector implements ContextSelector {
|
||||
/*
|
||||
* whether to use a one-level callstring context in addition to the apply
|
||||
* context
|
||||
*/
|
||||
private static final boolean USE_ONE_LEVEL = true;
|
||||
/* whether to use a one-level callstring context in addition to the apply context */
|
||||
private static final boolean USE_ONE_LEVEL = true;
|
||||
|
||||
private static final TypeName APPLY_TYPE_NAME = TypeName.findOrCreate("Lprologue.js/functionApply");
|
||||
|
||||
|
@ -73,11 +67,13 @@ public class JavaScriptFunctionApplyContextSelector implements ContextSelector {
|
|||
|
||||
}
|
||||
|
||||
private final ContextSelector base;
|
||||
private ContextSelector oneLevel;
|
||||
|
||||
public JavaScriptFunctionApplyContextSelector() {
|
||||
this.oneLevel = new nCFAContextSelector(1, new ContextInsensitiveSelector());
|
||||
// this.oneLevel = new OneLevelSiteContextSelector(base);
|
||||
public JavaScriptFunctionApplyContextSelector(ContextSelector base) {
|
||||
this.base = base;
|
||||
this.oneLevel = new nCFAContextSelector(1, base);
|
||||
// this.oneLevel = new OneLevelSiteContextSelector(base);
|
||||
}
|
||||
|
||||
public IntSet getRelevantParameters(CGNode caller, CallSiteReference site) {
|
||||
|
@ -85,19 +81,22 @@ public class JavaScriptFunctionApplyContextSelector implements ContextSelector {
|
|||
// for this arg of function being invoked,
|
||||
// 3 for arguments array
|
||||
if (caller.getIR().getCalls(site)[0].getNumberOfUses() >= 4) {
|
||||
return IntSetUtil.make(new int[] { 3 });
|
||||
return IntSetUtil.make(new int[] { 3 }).union(base.getRelevantParameters(caller, site));
|
||||
} else {
|
||||
return EmptyIntSet.instance;
|
||||
return base.getRelevantParameters(caller, site);
|
||||
}
|
||||
}
|
||||
|
||||
public static class ApplyContext implements Context {
|
||||
private final Context delegate;
|
||||
|
||||
/**
|
||||
* was the argsList argument a non-null Array?
|
||||
*/
|
||||
private final BooleanContextItem isNonNullArray;
|
||||
|
||||
ApplyContext(boolean isNonNullArray) {
|
||||
ApplyContext(Context delegate, boolean isNonNullArray) {
|
||||
this.delegate = delegate;
|
||||
this.isNonNullArray = new BooleanContextItem(isNonNullArray);
|
||||
}
|
||||
|
||||
|
@ -105,7 +104,7 @@ public class JavaScriptFunctionApplyContextSelector implements ContextSelector {
|
|||
if (APPLY_NON_NULL_ARGS.equals(name)) {
|
||||
return isNonNullArray;
|
||||
} else {
|
||||
return null;
|
||||
return delegate.get(name);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -113,7 +112,8 @@ public class JavaScriptFunctionApplyContextSelector implements ContextSelector {
|
|||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((isNonNullArray == null) ? 0 : isNonNullArray.hashCode());
|
||||
result = prime * result + delegate.hashCode();
|
||||
result = prime * result + isNonNullArray.hashCode();
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -126,17 +126,16 @@ public class JavaScriptFunctionApplyContextSelector implements ContextSelector {
|
|||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
ApplyContext other = (ApplyContext) obj;
|
||||
if (isNonNullArray == null) {
|
||||
if (other.isNonNullArray != null)
|
||||
return false;
|
||||
} else if (!isNonNullArray.equals(other.isNonNullArray))
|
||||
if (!delegate.equals(other.delegate))
|
||||
return false;
|
||||
if (!isNonNullArray.equals(other.isNonNullArray))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ApplyContext [isNonNullArray=" + isNonNullArray + "]";
|
||||
return "ApplyContext [delegate=" + delegate + ", isNonNullArray=" + isNonNullArray + "]";
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -144,6 +143,7 @@ public class JavaScriptFunctionApplyContextSelector implements ContextSelector {
|
|||
public Context getCalleeTarget(CGNode caller, CallSiteReference site, IMethod callee, InstanceKey[] receiver) {
|
||||
IClass declaringClass = callee.getDeclaringClass();
|
||||
IMethod method = declaringClass.getMethod(AstMethodReference.fnSelector);
|
||||
Context baseCtxt = base.getCalleeTarget(caller, site, callee, receiver);
|
||||
if (method != null) {
|
||||
TypeName tn = method.getReference().getDeclaringClass().getName();
|
||||
if (tn.equals(APPLY_TYPE_NAME)) {
|
||||
|
@ -154,13 +154,12 @@ public class JavaScriptFunctionApplyContextSelector implements ContextSelector {
|
|||
isNonNullArray = true;
|
||||
}
|
||||
}
|
||||
Context result = new ApplyContext(isNonNullArray);
|
||||
if (USE_ONE_LEVEL)
|
||||
result = new DelegatingContext(result, oneLevel.getCalleeTarget(caller, site, callee, receiver));
|
||||
return result;
|
||||
baseCtxt = oneLevel.getCalleeTarget(caller, site, callee, receiver);
|
||||
return new ApplyContext(baseCtxt, isNonNullArray);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
return baseCtxt;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -17,27 +17,30 @@ import com.ibm.wala.ssa.SSAOptions;
|
|||
import com.ibm.wala.ssa.SSAReturnInstruction;
|
||||
import com.ibm.wala.types.MethodReference;
|
||||
import com.ibm.wala.util.collections.HashMapFactory;
|
||||
import com.ibm.wala.util.intset.EmptyIntSet;
|
||||
import com.ibm.wala.util.intset.IntSet;
|
||||
import com.ibm.wala.util.intset.IntSetUtil;
|
||||
|
||||
public class ObjectSensitivityContextSelector implements ContextSelector {
|
||||
|
||||
private final ContextSelector base;
|
||||
|
||||
public ObjectSensitivityContextSelector(ContextSelector base) {
|
||||
this.base = base;
|
||||
}
|
||||
|
||||
private final HashMap<MethodReference, Boolean> returnsThis_cache = HashMapFactory.make();
|
||||
|
||||
|
||||
// determine whether the method returns "this"
|
||||
private boolean returnsThis(IMethod method) {
|
||||
MethodReference mref = method.getReference();
|
||||
if (method.getNumberOfParameters() < 1)
|
||||
if(method.getNumberOfParameters() < 1)
|
||||
return false;
|
||||
Boolean b = returnsThis_cache.get(mref);
|
||||
if (b != null)
|
||||
if(b != null)
|
||||
return b;
|
||||
for (SSAInstruction inst : ForInContextSelector.factory.makeIR(method, Everywhere.EVERYWHERE, SSAOptions.defaultOptions())
|
||||
.getInstructions()) {
|
||||
if (inst instanceof SSAReturnInstruction) {
|
||||
SSAReturnInstruction ret = (SSAReturnInstruction) inst;
|
||||
if (ret.getResult() == 2) {
|
||||
for(SSAInstruction inst : ForInContextSelector.factory.makeIR(method, Everywhere.EVERYWHERE, SSAOptions.defaultOptions()).getInstructions()) {
|
||||
if(inst instanceof SSAReturnInstruction) {
|
||||
SSAReturnInstruction ret = (SSAReturnInstruction)inst;
|
||||
if(ret.getResult() == 2) {
|
||||
returnsThis_cache.put(mref, true);
|
||||
return true;
|
||||
}
|
||||
|
@ -48,46 +51,49 @@ public class ObjectSensitivityContextSelector implements ContextSelector {
|
|||
}
|
||||
|
||||
public Context getCalleeTarget(CGNode caller, CallSiteReference site, IMethod callee, InstanceKey[] arguments) {
|
||||
if (returnsThis(callee)) {
|
||||
if (arguments.length > 1 && arguments[1] != null) {
|
||||
return new ArgumentInstanceContext(1, arguments[1]);
|
||||
Context baseContext = base.getCalleeTarget(caller, site, callee, arguments);
|
||||
if(returnsThis(callee)) {
|
||||
if(arguments.length > 1 && arguments[1] != null) {
|
||||
return new ArgumentInstanceContext(baseContext, 1, arguments[1]);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
return baseContext;
|
||||
}
|
||||
|
||||
public IntSet getRelevantParameters(CGNode caller, CallSiteReference site) {
|
||||
if (caller.getIR().getCalls(site)[0].getNumberOfUses() > 1) {
|
||||
return IntSetUtil.make(new int[] { 1 });
|
||||
return IntSetUtil.make(new int[]{1}).union(base.getRelevantParameters(caller, site));
|
||||
} else {
|
||||
return EmptyIntSet.instance;
|
||||
return base.getRelevantParameters(caller, site);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class ArgumentInstanceContext implements Context {
|
||||
private final Context base;
|
||||
private final int index;
|
||||
private final InstanceKey instanceKey;
|
||||
|
||||
public ArgumentInstanceContext(int index, InstanceKey instanceKey) {
|
||||
public ArgumentInstanceContext(Context base, int index, InstanceKey instanceKey) {
|
||||
this.base = base;
|
||||
this.index = index;
|
||||
this.instanceKey = instanceKey;
|
||||
}
|
||||
|
||||
public ContextItem get(ContextKey name) {
|
||||
/*
|
||||
* if(name == ContextKey.RECEIVER && index == 1) return instanceKey;
|
||||
*/
|
||||
if (name == ContextKey.PARAMETERS[index])
|
||||
/*if(name == ContextKey.RECEIVER && index == 1)
|
||||
return instanceKey;*/
|
||||
if(name == ContextKey.PARAMETERS[index])
|
||||
return new FilteredPointerKey.SingleInstanceFilter(instanceKey);
|
||||
return null;
|
||||
return base.get(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((base == null) ? 0 : base.hashCode());
|
||||
result = prime * result + index;
|
||||
result = prime * result + ((instanceKey == null) ? 0 : instanceKey.hashCode());
|
||||
return result;
|
||||
|
@ -102,6 +108,11 @@ class ArgumentInstanceContext implements Context {
|
|||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
ArgumentInstanceContext other = (ArgumentInstanceContext) obj;
|
||||
if (base == null) {
|
||||
if (other.base != null)
|
||||
return false;
|
||||
} else if (!base.equals(other.base))
|
||||
return false;
|
||||
if (index != other.index)
|
||||
return false;
|
||||
if (instanceKey == null) {
|
||||
|
@ -111,5 +122,5 @@ class ArgumentInstanceContext implements Context {
|
|||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -27,7 +27,6 @@ import com.ibm.wala.util.collections.IteratorPlusOne;
|
|||
import com.ibm.wala.util.collections.MapUtil;
|
||||
import com.ibm.wala.util.collections.NonNullSingletonIterator;
|
||||
import com.ibm.wala.util.collections.Pair;
|
||||
import com.ibm.wala.util.intset.EmptyIntSet;
|
||||
import com.ibm.wala.util.intset.IntSet;
|
||||
|
||||
public final class LexicalScopingResolverContexts implements ContextSelector {
|
||||
|
@ -439,8 +438,10 @@ public final class LexicalScopingResolverContexts implements ContextSelector {
|
|||
|
||||
private class LexicalScopingResolverContext implements Context {
|
||||
private final LexicalScopingResolver governingCallSites;
|
||||
private final Context base;
|
||||
|
||||
public int hashCode() {
|
||||
return (governingCallSites == null ? 1077651 : governingCallSites.hashCode());
|
||||
return base.hashCode() * (governingCallSites == null ? 1077651 : governingCallSites.hashCode());
|
||||
}
|
||||
|
||||
public boolean equals(Object o) {
|
||||
|
@ -448,35 +449,39 @@ public final class LexicalScopingResolverContexts implements ContextSelector {
|
|||
return true;
|
||||
} else if (getClass().equals(o.getClass())) {
|
||||
LexicalScopingResolverContext c = (LexicalScopingResolverContext) o;
|
||||
return (governingCallSites == c.governingCallSites);
|
||||
return (base == null ? c.base == null : base.equals(c.base)) && (governingCallSites == c.governingCallSites);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public ContextItem get(ContextKey name) {
|
||||
return name.equals(RESOLVER) ? governingCallSites: null;
|
||||
return name.equals(RESOLVER) ? governingCallSites : base != null ? base.get(name) : null;
|
||||
}
|
||||
|
||||
private LexicalScopingResolverContext(LexicalScopingResolver governingCallSites) {
|
||||
private LexicalScopingResolverContext(LexicalScopingResolver governingCallSites, Context base) {
|
||||
this.base = base;
|
||||
this.governingCallSites = governingCallSites;
|
||||
}
|
||||
|
||||
private LexicalScopingResolverContext(CGNode source, CallSiteReference callSite) {
|
||||
private LexicalScopingResolverContext(CGNode source, CallSiteReference callSite, Context base) {
|
||||
this.base = base;
|
||||
this.governingCallSites = findChild(source, callSite);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "LexicalScopingResolverContext [governingCallSites=" + governingCallSites + "]";
|
||||
return "LexicalScopingResolverContext [governingCallSites=" + governingCallSites + ", base=" + base + "]";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private final ContextSelector base;
|
||||
|
||||
private final PropagationCallGraphBuilder builder;
|
||||
|
||||
public LexicalScopingResolverContexts(PropagationCallGraphBuilder builder) {
|
||||
public LexicalScopingResolverContexts(PropagationCallGraphBuilder builder, ContextSelector base) {
|
||||
this.base = base;
|
||||
this.builder = builder;
|
||||
}
|
||||
|
||||
|
@ -557,11 +562,12 @@ public final class LexicalScopingResolverContexts implements ContextSelector {
|
|||
}
|
||||
|
||||
public Context getCalleeTarget(CGNode caller, CallSiteReference site, IMethod callee, InstanceKey[] actualParameters) {
|
||||
Context baseContext = base.getCalleeTarget(caller, site, callee, actualParameters);
|
||||
if (callee instanceof SummarizedMethod) {
|
||||
final String calleeName = callee.getReference().toString();
|
||||
// TODO create a sub-class in the cast.js projects so we're not checking strings here
|
||||
if (calleeName.equals("< JavaScriptLoader, LArray, ctor()LRoot; >") || calleeName.equals("< JavaScriptLoader, LObject, ctor()LRoot; >")) {
|
||||
return null;
|
||||
return baseContext;
|
||||
}
|
||||
}
|
||||
LexicalScopingResolver resolver = (LexicalScopingResolver) caller.getContext().get(RESOLVER);
|
||||
|
@ -575,23 +581,23 @@ public final class LexicalScopingResolverContexts implements ContextSelector {
|
|||
}
|
||||
|
||||
if (caller.getMethod() instanceof AstMethod && hasExposedUses(caller, site)) {
|
||||
LexicalScopingResolverContext result = new LexicalScopingResolverContext(caller, site);
|
||||
LexicalScopingResolverContext result = new LexicalScopingResolverContext(caller, site, baseContext);
|
||||
MapUtil.findOrCreateList(key2Contexts, key).add(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
else if (resolver != null) {
|
||||
LexicalScopingResolverContext result = new LexicalScopingResolverContext(resolver);
|
||||
LexicalScopingResolverContext result = new LexicalScopingResolverContext(resolver, baseContext);
|
||||
MapUtil.findOrCreateList(key2Contexts, key).add(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
else {
|
||||
return null;
|
||||
return baseContext;
|
||||
}
|
||||
}
|
||||
|
||||
public IntSet getRelevantParameters(CGNode caller, CallSiteReference site) {
|
||||
return EmptyIntSet.instance;
|
||||
return base.getRelevantParameters(caller, site);
|
||||
}
|
||||
}
|
|
@ -9,6 +9,7 @@ import com.ibm.wala.ipa.callgraph.Context;
|
|||
import com.ibm.wala.ipa.callgraph.ContextItem;
|
||||
import com.ibm.wala.ipa.callgraph.ContextKey;
|
||||
import com.ibm.wala.ipa.callgraph.ContextSelector;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.AllocationSiteInNode;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.InstanceKey;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.cfa.CallerSiteContext;
|
||||
import com.ibm.wala.ipa.summaries.SummarizedMethod;
|
||||
|
@ -24,9 +25,11 @@ public class ScopeMappingKeysContextSelector implements ContextSelector {
|
|||
};
|
||||
|
||||
public static class ScopeMappingContext implements Context {
|
||||
private final Context base;
|
||||
private final ScopeMappingInstanceKey key;
|
||||
|
||||
private ScopeMappingContext(ScopeMappingInstanceKey key) {
|
||||
private ScopeMappingContext(Context base, ScopeMappingInstanceKey key) {
|
||||
this.base = base;
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
|
@ -34,7 +37,7 @@ public class ScopeMappingKeysContextSelector implements ContextSelector {
|
|||
if (scopeKey.equals(name)) {
|
||||
return key;
|
||||
} else {
|
||||
return null;
|
||||
return base.get(name);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -42,7 +45,7 @@ public class ScopeMappingKeysContextSelector implements ContextSelector {
|
|||
|
||||
public int hashCode() {
|
||||
if (hashcode == -1) {
|
||||
hashcode = key.hashCode();
|
||||
hashcode = base.hashCode() * key.hashCode();
|
||||
}
|
||||
return hashcode;
|
||||
}
|
||||
|
@ -52,30 +55,37 @@ public class ScopeMappingKeysContextSelector implements ContextSelector {
|
|||
}
|
||||
|
||||
public boolean equals(Object o) {
|
||||
return (o instanceof ScopeMappingContext) && key.equals(((ScopeMappingContext) o).key);
|
||||
return (o instanceof ScopeMappingContext) && key.equals(((ScopeMappingContext) o).key)
|
||||
&& base.equals(((ScopeMappingContext) o).base);
|
||||
}
|
||||
}
|
||||
|
||||
private final ContextSelector base;
|
||||
|
||||
public ScopeMappingKeysContextSelector(ContextSelector base) {
|
||||
this.base = base;
|
||||
}
|
||||
|
||||
public Context getCalleeTarget(CGNode caller, CallSiteReference site, IMethod callee, InstanceKey[] receiver) {
|
||||
Context bc = base.getCalleeTarget(caller, site, callee, receiver);
|
||||
if (callee instanceof SummarizedMethod) {
|
||||
final String calleeName = callee.getReference().toString();
|
||||
if (calleeName.equals("< JavaScriptLoader, LArray, ctor()LRoot; >")
|
||||
|| calleeName.equals("< JavaScriptLoader, LObject, ctor()LRoot; >")) {
|
||||
return null;
|
||||
return bc;
|
||||
}
|
||||
}
|
||||
if (receiver[0] instanceof ScopeMappingInstanceKey) {
|
||||
final ScopeMappingInstanceKey smik = (ScopeMappingInstanceKey) receiver[0];
|
||||
if (AstTranslator.NEW_LEXICAL) {
|
||||
if (detectRecursion(smik.getCreator().getContext(), callee)) {
|
||||
return null;
|
||||
return bc;
|
||||
}
|
||||
}
|
||||
final ScopeMappingContext scopeMappingContext = new ScopeMappingContext(smik);
|
||||
final ScopeMappingContext scopeMappingContext = new ScopeMappingContext(bc, smik);
|
||||
return scopeMappingContext;
|
||||
} else {
|
||||
return null;
|
||||
return bc;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,92 +0,0 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2007 IBM Corporation.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IBM Corporation - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package com.ibm.wala.ipa.callgraph;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import com.ibm.wala.classLoader.CallSiteReference;
|
||||
import com.ibm.wala.classLoader.IMethod;
|
||||
import com.ibm.wala.ipa.callgraph.impl.Everywhere;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.InstanceKey;
|
||||
import com.ibm.wala.util.intset.IntSet;
|
||||
|
||||
/**
|
||||
* A ContextSelector that behaves as the composition of a list of child
|
||||
* selectors. Note that we deliberately do not document what order the
|
||||
* composition is performed in, with the hope that the {@link ContextKey}s
|
||||
* understood by the {@link Context}s returned by distinct children do not
|
||||
* overlap.
|
||||
*
|
||||
*/
|
||||
public class ComposedContextSelector implements ContextSelector {
|
||||
|
||||
private final List<ContextSelector> childSelectors;
|
||||
|
||||
public ComposedContextSelector(Collection<ContextSelector> childSelectors) {
|
||||
this.childSelectors = new ArrayList<ContextSelector>(childSelectors);
|
||||
}
|
||||
|
||||
public ComposedContextSelector(ContextSelector... childSelectors) {
|
||||
this.childSelectors = Arrays.asList(childSelectors);
|
||||
}
|
||||
|
||||
/**
|
||||
* return a context representing the composition of all the non-null child
|
||||
* contexts. Elides the {@link Everywhere#EVERYWHERE} context when some child
|
||||
* returns a context that is not {@link Everywhere#EVERYWHERE}.
|
||||
*/
|
||||
public Context getCalleeTarget(CGNode caller, CallSiteReference site, IMethod callee, InstanceKey[] actualParameters) {
|
||||
List<Context> childResults = new ArrayList<Context>(1);
|
||||
boolean sawEverywhere = false;
|
||||
for (ContextSelector child : childSelectors) {
|
||||
Context childResult = child.getCalleeTarget(caller, site, callee, actualParameters);
|
||||
if (childResult != null) {
|
||||
childResults.add(childResult);
|
||||
if (sawEverywhere) {
|
||||
assert !childResult.equals(Everywhere.EVERYWHERE);
|
||||
} else {
|
||||
sawEverywhere = childResult.equals(Everywhere.EVERYWHERE);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (childResults.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
boolean elideEverywhere = sawEverywhere && childResults.size() > 1;
|
||||
Context result = null;
|
||||
for (Context c : childResults) {
|
||||
if (!elideEverywhere || !c.equals(Everywhere.EVERYWHERE)) {
|
||||
result = (result == null) ? c : new DelegatingContext(c, result);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* return the union of the relevant parameters for all children
|
||||
*/
|
||||
public IntSet getRelevantParameters(CGNode caller, CallSiteReference site) {
|
||||
IntSet result = null;
|
||||
for (ContextSelector child : childSelectors) {
|
||||
IntSet childResult = child.getRelevantParameters(caller, site);
|
||||
if (result == null) {
|
||||
result = childResult;
|
||||
} else {
|
||||
result = result.union(childResult);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
|
@ -13,7 +13,6 @@ package com.ibm.wala.ipa.callgraph.propagation.cfa;
|
|||
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.ComposedContextSelector;
|
||||
import com.ibm.wala.ipa.callgraph.Context;
|
||||
import com.ibm.wala.ipa.callgraph.ContextItem;
|
||||
import com.ibm.wala.ipa.callgraph.ContextKey;
|
||||
|
@ -67,9 +66,6 @@ public abstract class CallStringContextSelector implements ContextSelector {
|
|||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* TODO get rid of base selector, and instead use with {@link ComposedContextSelector}
|
||||
*/
|
||||
private final ContextSelector base;
|
||||
|
||||
public CallStringContextSelector(ContextSelector base) {
|
||||
|
|
|
@ -13,7 +13,6 @@ package com.ibm.wala.ipa.callgraph.propagation.cfa;
|
|||
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.ComposedContextSelector;
|
||||
import com.ibm.wala.ipa.callgraph.Context;
|
||||
import com.ibm.wala.ipa.callgraph.ContextSelector;
|
||||
import com.ibm.wala.ipa.callgraph.impl.Everywhere;
|
||||
|
@ -25,9 +24,6 @@ import com.ibm.wala.util.intset.IntSet;
|
|||
*/
|
||||
public class OneLevelSiteContextSelector implements ContextSelector {
|
||||
|
||||
/**
|
||||
* TODO get rid of base selector, and instead use with {@link ComposedContextSelector}
|
||||
*/
|
||||
private final ContextSelector baseSelector;
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue