pascal.taie.analysis.pta.toolkit.PointerAnalysisResultExImpl Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of tai-e Show documentation
Show all versions of tai-e Show documentation
An easy-to-learn/use static analysis framework for Java
The newest version!
/*
* Tai-e: A Static Analysis Framework for Java
*
* Copyright (C) 2022 Tian Tan
* Copyright (C) 2022 Yue Li
*
* This file is part of Tai-e.
*
* Tai-e is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation, either version 3
* of the License, or (at your option) any later version.
*
* Tai-e is distributed in the hope that it will be useful,but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General
* Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with Tai-e. If not, see .
*/
package pascal.taie.analysis.pta.toolkit;
import pascal.taie.analysis.pta.PointerAnalysisResult;
import pascal.taie.analysis.pta.core.heap.Obj;
import pascal.taie.ir.exp.Var;
import pascal.taie.language.classes.JMethod;
import pascal.taie.language.type.Type;
import pascal.taie.util.collection.Maps;
import pascal.taie.util.collection.MultiMap;
import java.util.Set;
public class PointerAnalysisResultExImpl implements PointerAnalysisResultEx {
private final PointerAnalysisResult base;
/**
* Constructs an extended pointer analysis result.
*
* @param base base pointer analysis result
* @param eagerInit whether initialize all fields eagerly; if this result
* will be accessed in concurrent setting, then the caller
* should give {@code true}.
*/
public PointerAnalysisResultExImpl(
PointerAnalysisResult base, boolean eagerInit) {
this.base = base;
if (eagerInit) {
initMethodReceiverObjects();
initAllocatedObjects();
initType2Objects();
}
}
@Override
public PointerAnalysisResult getBase() {
return base;
}
/**
* Map from each receiver object to the methods invoked on it.
*/
private MultiMap recv2Methods;
@Override
public Set getMethodsInvokedOn(Obj obj) {
MultiMap map = recv2Methods;
if (map == null) {
initMethodReceiverObjects();
map = recv2Methods;
}
return map.get(obj);
}
/**
* Map from each method to its receiver objects.
*/
private MultiMap method2Recvs;
@Override
public Set getReceiverObjectsOf(JMethod method) {
MultiMap map = method2Recvs;
if (map == null) {
initMethodReceiverObjects();
map = method2Recvs;
}
return map.get(method);
}
private void initMethodReceiverObjects() {
MultiMap r2m = Maps.newMultiMap();
MultiMap m2r = Maps.newMultiMap();
for (JMethod method : base.getCallGraph()) {
if (!method.isStatic()) {
Var thisVar = method.getIR().getThis();
for (Obj recv : base.getPointsToSet(thisVar)) {
r2m.put(recv, method);
m2r.put(method, recv);
}
}
}
recv2Methods = r2m;
method2Recvs = m2r;
}
/**
* Map from each method to the objects allocated in it.
*/
private MultiMap method2Objs;
@Override
public Set getObjectsAllocatedIn(JMethod method) {
MultiMap map = method2Objs;
if (map == null) {
initAllocatedObjects();
map = method2Objs;
}
return map.get(method);
}
private void initAllocatedObjects() {
MultiMap map = Maps.newMultiMap();
for (Obj obj : base.getObjects()) {
obj.getContainerMethod().ifPresent(m -> map.put(m, obj));
}
method2Objs = map;
}
/**
* Map from each type to the objects of the type.
*/
private MultiMap type2Objs;
@Override
public Set getObjectsOf(Type type) {
MultiMap map = type2Objs;
if (map == null) {
initType2Objects();
map = type2Objs;
}
return map.get(type);
}
@Override
public Set getObjectTypes() {
MultiMap map = type2Objs;
if (map == null) {
initType2Objects();
map = type2Objs;
}
return map.keySet();
}
private void initType2Objects() {
MultiMap map = Maps.newMultiMap();
for (Obj obj : base.getObjects()) {
map.put(obj.getType(), obj);
}
type2Objs = map;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy