use of de.fraunhofer.aisec.cpg.graph.HasType in project cpg by Fraunhofer-AISEC.
the class ValueDeclaration method setType.
@Override
public void setType(Type type, Collection<HasType> root) {
if (!TypeManager.isTypeSystemActive()) {
TypeManager.getInstance().cacheType(this, type);
return;
}
if (root == null) {
root = new ArrayList<>();
}
if (type == null || root.contains(this) || TypeManager.getInstance().isUnknown(type) || (this.type instanceof FunctionPointerType && !(type instanceof FunctionPointerType))) {
return;
}
Type oldType = this.type;
type = type.duplicate();
type.setQualifier(this.type.getQualifier().merge(type.getQualifier()));
Set<Type> subTypes = new HashSet<>();
for (Type t : getPossibleSubTypes()) {
if (!t.isSimilar(type)) {
subTypes.add(t);
}
}
subTypes.add(type);
this.type = TypeManager.getInstance().registerType(TypeManager.getInstance().getCommonType(subTypes).orElse(type));
Set<Type> newSubtypes = new HashSet<>();
for (var s : subTypes) {
if (TypeManager.getInstance().isSupertypeOf(this.type, s)) {
newSubtypes.add(TypeManager.getInstance().registerType(s));
}
}
setPossibleSubTypes(newSubtypes);
if (Objects.equals(oldType, type)) {
// Nothing changed, so we do not have to notify the listeners.
return;
}
// Add current node to the set of "triggers" to detect potential loops.
root.add(this);
// Notify all listeners about the changed type
for (var l : typeListeners) {
if (!l.equals(this)) {
l.typeChanged(this, root, oldType);
}
}
}
use of de.fraunhofer.aisec.cpg.graph.HasType in project cpg by Fraunhofer-AISEC.
the class ValueDeclaration method resetTypes.
@Override
public void resetTypes(Type type) {
Set<Type> oldSubTypes = new HashSet<>(getPossibleSubTypes());
Type oldType = this.type;
this.type = type;
setPossibleSubTypes(new HashSet<>(List.of(type)));
List<HasType> root = new ArrayList<>(List.of(this));
if (!Objects.equals(oldType, type)) {
this.typeListeners.stream().filter(l -> !l.equals(this)).forEach(l -> l.typeChanged(this, root, oldType));
}
if (oldSubTypes.size() != 1 || !oldSubTypes.contains(type))
this.typeListeners.stream().filter(l -> !l.equals(this)).forEach(l -> l.possibleSubTypesChanged(this, root, oldSubTypes));
}
use of de.fraunhofer.aisec.cpg.graph.HasType in project cpg by Fraunhofer-AISEC.
the class ArrayCreationExpression method typeChanged.
@Override
public void typeChanged(HasType src, Collection<HasType> root, Type oldType) {
if (!TypeManager.isTypeSystemActive()) {
return;
}
Type previous = this.type;
setType(src.getPropagationType(), root);
if (!previous.equals(this.type)) {
this.type.setTypeOrigin(Type.Origin.DATAFLOW);
}
}
use of de.fraunhofer.aisec.cpg.graph.HasType in project cpg by Fraunhofer-AISEC.
the class UnaryOperator method getsDataFromInput.
private boolean getsDataFromInput(TypeListener curr, TypeListener target) {
List<TypeListener> worklist = new ArrayList<>();
worklist.add(curr);
while (!worklist.isEmpty()) {
TypeListener tl = worklist.remove(0);
if (!checked.contains(tl)) {
checked.add(tl);
if (tl == target) {
return true;
}
if (curr instanceof HasType) {
worklist.addAll(((HasType) curr).getTypeListeners());
}
}
}
return false;
}
use of de.fraunhofer.aisec.cpg.graph.HasType in project cpg by Fraunhofer-AISEC.
the class InitializerListExpression method typeChanged.
@Override
public void typeChanged(HasType src, Collection<HasType> root, Type oldType) {
if (!TypeManager.isTypeSystemActive()) {
return;
}
if (!TypeManager.getInstance().isUnknown(this.type) && src.getPropagationType().equals(oldType)) {
return;
}
Type previous = this.type;
Type newType;
Set<Type> subTypes;
if (this.getInitializers().contains(src)) {
Set<Type> types = this.initializers.parallelStream().map(PropertyEdge::getEnd).map(Expression::getType).filter(Objects::nonNull).map(t -> TypeManager.getInstance().registerType(t.reference(PointerOrigin.ARRAY))).collect(Collectors.toSet());
Type alternative = !types.isEmpty() ? types.iterator().next() : UnknownType.getUnknownType();
newType = TypeManager.getInstance().getCommonType(types).orElse(alternative);
subTypes = new HashSet<>(getPossibleSubTypes());
subTypes.remove(oldType);
subTypes.addAll(types);
} else {
newType = src.getType();
subTypes = new HashSet<>(getPossibleSubTypes());
subTypes.remove(oldType);
subTypes.add(newType);
}
setType(newType, root);
setPossibleSubTypes(subTypes, root);
if (!previous.equals(this.type)) {
this.type.setTypeOrigin(Type.Origin.DATAFLOW);
}
}
Aggregations