public PType intersect ( PType a , PType b ) { Set < PType > tsa = new HashSet < PType > ( ) ; Set < PType > tsb = new HashSet < PType > ( ) ; // Obtain the fundamental type of BracketTypes, NamedTypes and OptionalTypes. boolean resolved = false ; while ( ! resolved ) { if ( a instanceof ABracketType ) { a = ( ( ABracketType ) a ) . getType ( ) ; continue ; } if ( b instanceof ABracketType ) { b = ( ( ABracketType ) b ) . getType ( ) ; continue ; } if ( a instanceof ANamedInvariantType ) { ANamedInvariantType nt = ( ANamedInvariantType ) a ; if ( nt . getInvDef ( ) == null ) { a = nt . getType ( ) ; continue ; } } if ( b instanceof ANamedInvariantType ) { ANamedInvariantType nt = ( ANamedInvariantType ) b ; if ( nt . getInvDef ( ) == null ) { b = nt . getType ( ) ; continue ; } } if ( a instanceof AOptionalType && b instanceof AOptionalType ) { a = ( ( AOptionalType ) a ) . getType ( ) ; b = ( ( AOptionalType ) b ) . getType ( ) ; continue ; } resolved = true ; } if ( a instanceof AUnionType ) { AUnionType uta = ( AUnionType ) a ; tsa . addAll ( uta . getTypes ( ) ) ; } else { tsa . add ( a ) ; } if ( b instanceof AUnionType ) { AUnionType utb = ( AUnionType ) b ; tsb . addAll ( utb . getTypes ( ) ) ; } else { tsb . add ( b ) ; } // Keep largest types which are compatible (eg. nat and int choses int) Set < PType > result = new HashSet < PType > ( ) ; for ( PType atype : tsa ) { for ( PType btype : tsb ) { if ( isSubType ( atype , btype ) ) { result . add ( btype ) ; } else if ( isSubType ( btype , atype ) ) { result . add ( atype ) ; } } } if ( result . isEmpty ( ) ) { return null ; } else { List < PType > list = new Vector < PType > ( ) ; list . addAll ( result ) ; return AstFactory . newAUnionType ( a . getLocation ( ) , list ) ; } }
Calculate the intersection of two types .