diff --git a/AlgebraicDataflowArchitectureModel/src/algorithms/TypeInference.java b/AlgebraicDataflowArchitectureModel/src/algorithms/TypeInference.java index d2c98ef..7b6de77 100644 --- a/AlgebraicDataflowArchitectureModel/src/algorithms/TypeInference.java +++ b/AlgebraicDataflowArchitectureModel/src/algorithms/TypeInference.java @@ -833,11 +833,33 @@ private static Type createNewListType(Type compType, Type parentType) { String compTypeName = getInterfaceTypeName(compType); + List childrenTypes = getChildrenTypesOfList(parentType); Type newListType = new Type("List", "ArrayList<>", "List<" + compTypeName + ">", parentType); listTypes.put(compType, newListType); listComponentTypes.put(newListType, compType); + for (Type childType: childrenTypes) { + if (compareTypes(childType, newListType)) { + if (newListType.getParentTypes().contains(parentType)) { + newListType.replaceParentType(parentType, childType); + } else { + newListType.addParentType(childType); + } + } else if (compareTypes(newListType, childType)) { + childType.replaceParentType(parentType, newListType); + } + } return newListType; } + + private static List getChildrenTypesOfList(Type parentListType) { + List childrenTypes = new ArrayList<>(); + for (Type listType: listComponentTypes.keySet()) { + if (listType.getParentTypes().contains(parentListType)) { + childrenTypes.add(listType); + } + } + return childrenTypes; + } private static void updateTupleTypes(Expression exp, Map tuple, Map> expToTuple, Map> updateFromTuple) { List components = expToTuple.get(System.identityHashCode(exp)); @@ -847,6 +869,7 @@ Type tupleType = tuple.get(System.identityHashCode(components)); Type newTupleType = getExpTypeIfUpdatable(tupleType, exp); if (newTupleType != null) { + // Propagate an update of a tuple's type to its components' types. tuple.put(System.identityHashCode(components), newTupleType); List componentTypes = tupleComponentTypes.get(newTupleType); Map updateExps = getUpdateSet(updateFromTuple, components); @@ -871,6 +894,7 @@ Type compType = componentTypes.get(idx - 1); Type newCompType = getExpTypeIfUpdatable(compType, exp); if (newCompType != null) { + // Propagate an update of a component's type to its container's (tuple's) type. componentTypes = new ArrayList<>(componentTypes); componentTypes.set(idx - 1, newCompType); Type newTupleType = tupleTypes.get(componentTypes); @@ -905,12 +929,34 @@ implTypeName = implTypeName.replace("$x", ", " + getImplementationTypeName(componentTypes.get(componentTypes.size() - 1))); interfaceTypeName = interfaceTypeName.replace("$x", ", " + getInterfaceTypeName(componentTypes.get(componentTypes.size() - 1))); } + List childrenTypes = getChildrenTypesOfTuple(parentTupleType); Type newTupleType = new Type("Tuple", implTypeName, interfaceTypeName, parentTupleType); tupleTypes.put(componentTypes, newTupleType); tupleComponentTypes.put(newTupleType, componentTypes); + for (Type childType: childrenTypes) { + if (compareTypes(childType, newTupleType)) { + if (newTupleType.getParentTypes().contains(parentTupleType)) { + newTupleType.replaceParentType(parentTupleType, childType); + } else { + newTupleType.addParentType(childType); + } + } else if (compareTypes(newTupleType, childType)) { + childType.replaceParentType(parentTupleType, newTupleType); + } + } return newTupleType; } + private static List getChildrenTypesOfTuple(Type parentTupleType) { + List childrenTypes = new ArrayList<>(); + for (Type tupleType: tupleComponentTypes.keySet()) { + if (tupleType.getParentTypes().contains(parentTupleType)) { + childrenTypes.add(tupleType); + } + } + return childrenTypes; + } + private static String getImplementationTypeName(Type type) { if (type == null) return "Integer"; String wrapperType = DataConstraintModel.getWrapperType(type); @@ -947,6 +993,12 @@ return null; } + /** + * Is an given original type an ancestor of a given new type? + * @param originalType original type + * @param newType new type (may not have been registered) + * @return true: if the original type equals to the new type or is an ancestor of the new type, false: otherwise + */ private static boolean compareTypes(Type originalType, Type newType) { if (originalType == null) return true; if (originalType != newType && newType != null) {