Class SymTypeNormalizeVisitor

  • All Implemented Interfaces:
    ISymTypeVisitor

    public class SymTypeNormalizeVisitor
    extends SymTypeDeepCloneVisitor
    tries to normalize SymTypeExpressions, including, but not limited to, unions and intersections e.g., (A|A|B) -> A, if A extends B Usage: calculate(symType)

    normalization of regular expressions are not supported

    note, this visitor does not box/unbox, boxing/unboxing should be done before this visitor if required

    • Constructor Detail

      • SymTypeNormalizeVisitor

        public SymTypeNormalizeVisitor()
    • Method Detail

      • normalizeIntersectionWithoutUnions

        protected SymTypeExpression normalizeIntersectionWithoutUnions​(SymTypeOfIntersection intersection)
        normalizes an intersection the contained expressions are expected to be normalized and not unions s. visit(SymTypeOfIntersection)
      • intersect

        protected SymTypeExpression intersect​(java.util.Collection<SymTypeExpression> uniqueTypes)
        Intersects types and removes any redundant information (for normalized types without unions or intersections)
      • intersectFunctionTypes

        protected SymTypeExpression intersectFunctionTypes​(java.util.Collection<SymTypeOfFunction> functions)
        calculates the intersection of function types.

        IMPORTANT: This does filter out cases that can occur for overloaded functions, e.g., intersect(A -> B, (A, A) -> B) = bottom This is relevant if no type inference is used, and within type inference itself; With this version, resolved intersections MUST be split before normalization. An alternativ would be to allow the aforementioned kind of intersection, But that would lead to allowing values that are multiple function references at once. This is highly unintuitive and not supported by (most?) major languages.

        TODO FDr: Figure out if for the non-type-inference version the intersection has to be calculated differently (to allow for overloads), or if another representation for overloads would be better suited (which in turn would probably be turned into an intersection for the non-inference version anyway).

      • splitUnions

        protected java.util.Set<SymTypeExpression> splitUnions​(java.util.Set<SymTypeExpression> types)
        splits up unions e.g., {(A|(B|C)),D} -> {A,B,C,D} used for normalization
      • splitIntersections

        protected java.util.Set<SymTypeExpression> splitIntersections​(java.util.Set<SymTypeExpression> types)
        splits up intersections e.g., {(A&(B&C)),D} -> {A,B,C,D} used for normalization
      • intersectionOfUnions2UnionOfIntersections

        protected java.util.Set<SymTypeOfIntersection> intersectionOfUnions2UnionOfIntersections​(java.util.Set<SymTypeExpression> intersectedTypes)
        takes an intersection, which may contain unions and creates a union which contains intersections A&B&(C|D) -> (A&B&C)|(A&B&D) Note that this only calculates the given intersection, not the intersection contained within the given intersection. An additional characteristic to mention is that NO empty intersections / unions are created if there have been none to begin with
      • splitTupleByUnion

        protected java.util.List<SymTypeOfTuple> splitTupleByUnion​(SymTypeOfTuple tuple)
        Split tuples by unions. (A|B,C&D) -> (A,C&D), (B, C&D) does not create deep copies.
      • splitTupleByIntersection

        protected java.util.List<SymTypeOfTuple> splitTupleByIntersection​(SymTypeOfTuple tuple)
        Split tuples by intersections. (A|B,C&D) -> (A|B,C), (A|B, D) does not create deep copies.
      • errorIfEmpty

        protected void errorIfEmpty​(java.util.Collection<? extends SymTypeExpression> types)