WALA/com.ibm.wala.core/src/com/ibm/wala/ipa/callgraph/impl/UnionContextSelector.java

79 lines
2.9 KiB
Java

/******************************************************************************
* Copyright (c) 2002 - 2014 IBM Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this 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.impl;
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.DelegatingContext;
import com.ibm.wala.ipa.callgraph.propagation.InstanceKey;
import com.ibm.wala.util.intset.IntSet;
/**
* Checks ContextSelectors A and B, then returns the union of their findings.
*
* The returned Context contains the ContextKeys from A and B. If for a given key a value is
* generated by A as well as B the value generated by A has the precedence.
*
* As the UnionContextSelector optionally returns a DelegatingContext it cannot be used to
* anihilate ContextValues of B to null.
*
* @see com.ibm.wala.ipa.callgraph.impl.DelegatingContextSelector
*
* @author Tobias Blaschke <code@tobiasblaschke.de>
*/
public class UnionContextSelector implements ContextSelector {
private final ContextSelector A;
private final ContextSelector B;
public UnionContextSelector(final ContextSelector A, final ContextSelector B) {
if (A == null) {
throw new IllegalArgumentException("The ContextSelector given as A may not be null");
}
if (B == null) {
throw new IllegalArgumentException("The ContextSelector given as B may not be null");
}
this.A = A;
this.B = B;
}
/**
* If only one Context exists return it, else return a DelegatingContext.
*/
@Override
public Context getCalleeTarget(CGNode caller, CallSiteReference site, IMethod callee, InstanceKey[] receiver) {
final Context ctxA = A.getCalleeTarget(caller, site, callee, receiver);
final Context ctxB = B.getCalleeTarget(caller, site, callee, receiver);
if (ctxA == null) {
return ctxB;
} else if (ctxB == null) {
return ctxA;
} else {
final Context ctxU = new DelegatingContext(ctxA, ctxB);
return ctxU;
}
}
@Override
public IntSet getRelevantParameters(CGNode caller, CallSiteReference site) {
return A.getRelevantParameters(caller, site).union(B.getRelevantParameters(caller, site));
}
@Override
public String toString() {
return "<UnionContextSelector A=" + A + " B=" + B + " />";
}
}