Generate proper InstanceFieldKeys for property accesses with Numbers.
Note that this change actually breaks a couple of our unit tests. But, it seems they were only passing by accident before anyway, and this change at least leads to a more consistent handling of dynamic property accesses with String vs. Number property names.
This commit is contained in:
parent
6677587ff5
commit
6084f4ff61
|
@ -19,11 +19,13 @@ import com.ibm.wala.classLoader.IField;
|
|||
import com.ibm.wala.ipa.callgraph.AnalysisCache;
|
||||
import com.ibm.wala.ipa.callgraph.AnalysisOptions;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.ConcreteTypeKey;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.ConstantKey;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.InstanceKey;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.PointerKey;
|
||||
import com.ibm.wala.ipa.cha.IClassHierarchy;
|
||||
import com.ibm.wala.types.TypeReference;
|
||||
import com.ibm.wala.util.collections.EmptyIterator;
|
||||
import com.ibm.wala.util.strings.Atom;
|
||||
|
||||
/**
|
||||
* Common utilities for CFA-style call graph builders.
|
||||
|
@ -90,6 +92,29 @@ public abstract class JSCFABuilder extends JSSSAPropagationCallGraphBuilder {
|
|||
return super.getPointerKeysForReflectedFieldWrite(I, F);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected PointerKey getInstanceFieldPointerKeyForConstant(InstanceKey I, ConstantKey F) {
|
||||
Object v = F.getValue();
|
||||
if (v instanceof Double) {
|
||||
String strVal = simulateNumberToString((Double)v);
|
||||
IField f = I.getConcreteType().getField(Atom.findOrCreateUnicodeAtom((String) strVal));
|
||||
return getPointerKeyForInstanceField(I, f);
|
||||
|
||||
} else {
|
||||
return super.getInstanceFieldPointerKeyForConstant(I, F);
|
||||
}
|
||||
}
|
||||
|
||||
private String simulateNumberToString(Double v) {
|
||||
// TODO this is very incomplete --MS
|
||||
String result = v.toString();
|
||||
if (result.endsWith(".0")) {
|
||||
result = result.substring(0, result.length() - 2);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
});
|
||||
}
|
||||
|
|
|
@ -14,11 +14,13 @@ import java.util.Iterator;
|
|||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import com.ibm.wala.classLoader.IClass;
|
||||
import com.ibm.wala.classLoader.IField;
|
||||
import com.ibm.wala.ipa.callgraph.CGNode;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.ConcreteTypeKey;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.ConstantKey;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.FilteredPointerKey;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.InstanceFieldKey;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.InstanceKey;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.PointerKey;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.PointerKeyFactory;
|
||||
|
@ -68,28 +70,49 @@ public class DelegatingAstPointerKeys implements AstPointerKeyFactory {
|
|||
List<PointerKey> result = new LinkedList<PointerKey>();
|
||||
|
||||
if (F instanceof ConstantKey) {
|
||||
Object v = ((ConstantKey) F).getValue();
|
||||
if (v instanceof String) {
|
||||
IField f = I.getConcreteType().getField(Atom.findOrCreateUnicodeAtom((String) v));
|
||||
result.add(getPointerKeyForInstanceField(I, f));
|
||||
PointerKey ifk = getInstanceFieldPointerKeyForConstant(I, (ConstantKey) F);
|
||||
if (ifk != null) {
|
||||
result.add(ifk);
|
||||
}
|
||||
}
|
||||
|
||||
result.add(ReflectedFieldPointerKey.mapped(new ConcreteTypeKey(F.getConcreteType()), I));
|
||||
result.add(ReflectedFieldPointerKey.mapped(new ConcreteTypeKey(getFieldNameType(F)), I));
|
||||
|
||||
return result.iterator();
|
||||
}
|
||||
|
||||
public Iterator<PointerKey> getPointerKeysForReflectedFieldWrite(InstanceKey I, InstanceKey F) {
|
||||
/**
|
||||
* get type for F appropriate for use in a field name.
|
||||
*
|
||||
* @param F
|
||||
* @return
|
||||
*/
|
||||
protected IClass getFieldNameType(InstanceKey F) {
|
||||
return F.getConcreteType();
|
||||
}
|
||||
|
||||
/**
|
||||
* if F is a supported constant representing a field, return the corresponding {@link InstanceFieldKey} for I. Otherwise, return <code>null</code>.
|
||||
* @param F
|
||||
* @return
|
||||
*/
|
||||
protected PointerKey getInstanceFieldPointerKeyForConstant(InstanceKey I, ConstantKey F) {
|
||||
Object v = F.getValue();
|
||||
// FIXME: current only constant string are handled
|
||||
if (v instanceof String) {
|
||||
IField f = I.getConcreteType().getField(Atom.findOrCreateUnicodeAtom((String) v));
|
||||
return getPointerKeyForInstanceField(I, f);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public Iterator<PointerKey> getPointerKeysForReflectedFieldWrite(InstanceKey I, InstanceKey F) {
|
||||
if (F instanceof ConstantKey) {
|
||||
Object v = ((ConstantKey) F).getValue();
|
||||
if (v instanceof String) {
|
||||
IField f = I.getConcreteType().getField(Atom.findOrCreateUnicodeAtom((String) v));
|
||||
return new NonNullSingletonIterator<PointerKey>(getPointerKeyForInstanceField(I, f));
|
||||
PointerKey ifk = getInstanceFieldPointerKeyForConstant(I, (ConstantKey) F);
|
||||
if (ifk != null) {
|
||||
return new NonNullSingletonIterator<PointerKey>(ifk);
|
||||
}
|
||||
}
|
||||
|
||||
return new NonNullSingletonIterator<PointerKey>(ReflectedFieldPointerKey.mapped(new ConcreteTypeKey(F.getConcreteType()), I));
|
||||
return new NonNullSingletonIterator<PointerKey>(ReflectedFieldPointerKey.mapped(new ConcreteTypeKey(getFieldNameType(F)), I));
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue