79 lines
2.9 KiB
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 + " />";
|
|
}
|
|
}
|