private static boolean merge(
      final SymbolTable symbolTable,
      final int sourceType,
      final int[] dstTypes,
      final int dstIndex) {
    int dstType = dstTypes[dstIndex];
    if (dstType == sourceType) {
      // If the types are equal, merge(sourceType, dstType) = dstType, so there is no change.
      return false;
    }
    int srcType = sourceType;
    if ((sourceType & ~DIM_MASK) == NULL) {
      if (dstType == NULL) {
        return false;
      }
      srcType = NULL;
    }
    if (dstType == 0) {
      // If dstTypes[dstIndex] has never been assigned, merge(srcType, dstType) = srcType.
      dstTypes[dstIndex] = srcType;
      return true;
    }
    int mergedType;
    if ((dstType & DIM_MASK) != 0 || (dstType & KIND_MASK) == REFERENCE_KIND) {
      // If dstType is a reference type of any array dimension.
      if (srcType == NULL) {
        // If srcType is the NULL type, merge(srcType, dstType) = dstType, so there is no change.
        return false;
      } else if ((srcType & (DIM_MASK | KIND_MASK)) == (dstType & (DIM_MASK | KIND_MASK))) {
        // If srcType has the same array dimension and the same kind as dstType.
        if ((dstType & KIND_MASK) == REFERENCE_KIND) {
          // If srcType and dstType are reference types with the same array dimension,
          // merge(srcType, dstType) = dim(srcType) | common super class of srcType and dstType.
          mergedType =
              (srcType & DIM_MASK)
                  | REFERENCE_KIND
                  | symbolTable.addMergedType(srcType & VALUE_MASK, dstType & VALUE_MASK);
        } else {
          // If srcType and dstType are array types of equal dimension but different element types,
          // merge(srcType, dstType) = dim(srcType) - 1 | java/lang/Object.
          int mergedDim = ELEMENT_OF + (srcType & DIM_MASK);
          mergedType = mergedDim | REFERENCE_KIND | symbolTable.addType("java/lang/Object");
        }
      } else if ((srcType & DIM_MASK) != 0 || (srcType & KIND_MASK) == REFERENCE_KIND) {
        // If srcType is any other reference or array type,
        // merge(srcType, dstType) = min(srcDdim, dstDim) | java/lang/Object
        // where srcDim is the array dimension of srcType, minus 1 if srcType is an array type
        // with a non reference element type (and similarly for dstDim).
        int srcDim = srcType & DIM_MASK;
        if (srcDim != 0 && (srcType & KIND_MASK) != REFERENCE_KIND) {
          srcDim = ELEMENT_OF + srcDim;
        }
        int dstDim = dstType & DIM_MASK;
        if (dstDim != 0 && (dstType & KIND_MASK) != REFERENCE_KIND) {
          dstDim = ELEMENT_OF + dstDim;
        }
        mergedType =
            Math.min(srcDim, dstDim) | REFERENCE_KIND | symbolTable.addType("java/lang/Object");
      } else {
        // If srcType is any other type, merge(srcType, dstType) = TOP.
        mergedType = TOP;
      }
    } else if (dstType == NULL) {
      // If dstType is the NULL type, merge(srcType, dstType) = srcType, or TOP if srcType is not a
      // an array type or a reference type.
      mergedType =
          (srcType & DIM_MASK) != 0 || (srcType & KIND_MASK) == REFERENCE_KIND ? srcType : TOP;
    } else {
      // If dstType is any other type, merge(srcType, dstType) = TOP whatever srcType.
      mergedType = TOP;
    }
    if (mergedType != dstType) {
      dstTypes[dstIndex] = mergedType;
      return true;
    }
    return false;
  }
private static boolean merge(
      final SymbolTable symbolTable,
      final int sourceType,
      final int[] dstTypes,
      final int dstIndex) {
    int dstType = dstTypes[dstIndex];
    if (dstType == sourceType) {
      
      return false;
    }
    int srcType = sourceType;
    if ((sourceType & ~DIM_MASK) == NULL) {
      if (dstType == NULL) {
        return false;
      }
      srcType = NULL;
    }
    if (dstType == 0) {
      
      dstTypes[dstIndex] = srcType;
      return true;
    }
    int mergedType;
    if ((dstType & DIM_MASK) != 0 || (dstType & KIND_MASK) == REFERENCE_KIND) {
      
      if (srcType == NULL) {
        
        return false;
      } else if ((srcType & (DIM_MASK | KIND_MASK)) == (dstType & (DIM_MASK | KIND_MASK))) {
        
        if ((dstType & KIND_MASK) == REFERENCE_KIND) {
          
          
          mergedType =
              (srcType & DIM_MASK)
                  | REFERENCE_KIND
                  | symbolTable.addMergedType(srcType & VALUE_MASK, dstType & VALUE_MASK);
        } else {
          
          
          int mergedDim = ELEMENT_OF + (srcType & DIM_MASK);
          mergedType = mergedDim | REFERENCE_KIND | symbolTable.addType("java/lang/Object");
        }
      } else if ((srcType & DIM_MASK) != 0 || (srcType & KIND_MASK) == REFERENCE_KIND) {
        
        
        
        
        int srcDim = srcType & DIM_MASK;
        if (srcDim != 0 && (srcType & KIND_MASK) != REFERENCE_KIND) {
          srcDim = ELEMENT_OF + srcDim;
        }
        int dstDim = dstType & DIM_MASK;
        if (dstDim != 0 && (dstType & KIND_MASK) != REFERENCE_KIND) {
          dstDim = ELEMENT_OF + dstDim;
        }
        mergedType =
            Math.min(srcDim, dstDim) | REFERENCE_KIND | symbolTable.addType("java/lang/Object");
      } else {
        
        mergedType = TOP;
      }
    } else if (dstType == NULL) {
      
      
      mergedType =
          (srcType & DIM_MASK) != 0 || (srcType & KIND_MASK) == REFERENCE_KIND ? srcType : TOP;
    } else {
      
      mergedType = TOP;
    }
    if (mergedType != dstType) {
      dstTypes[dstIndex] = mergedType;
      return true;
    }
    return false;
  }
private static boolean merge ( final SymbolTable symbolTable , final int sourceType , final int [ ] dstTypes , final int dstIndex ) { int dstType = dstTypes [ dstIndex ] ; if ( dstType == sourceType ) { // If the types are equal, merge(sourceType, dstType) = dstType, so there is no change. return false ; } int srcType = sourceType ; if ( ( sourceType & ~ DIM_MASK ) == NULL ) { if ( dstType == NULL ) { return false ; } srcType = NULL ; } if ( dstType == 0 ) { // If dstTypes[dstIndex] has never been assigned, merge(srcType, dstType) = srcType. dstTypes [ dstIndex ] = srcType ; return true ; } int mergedType ; if ( ( dstType & DIM_MASK ) != 0 || ( dstType & KIND_MASK ) == REFERENCE_KIND ) { // If dstType is a reference type of any array dimension. if ( srcType == NULL ) { // If srcType is the NULL type, merge(srcType, dstType) = dstType, so there is no change. return false ; } else if ( ( srcType & ( DIM_MASK | KIND_MASK ) ) == ( dstType & ( DIM_MASK | KIND_MASK ) ) ) { // If srcType has the same array dimension and the same kind as dstType. if ( ( dstType & KIND_MASK ) == REFERENCE_KIND ) { // If srcType and dstType are reference types with the same array dimension, // merge(srcType, dstType) = dim(srcType) | common super class of srcType and dstType. mergedType = ( srcType & DIM_MASK ) | REFERENCE_KIND | symbolTable . addMergedType ( srcType & VALUE_MASK , dstType & VALUE_MASK ) ; } else { // If srcType and dstType are array types of equal dimension but different element types, // merge(srcType, dstType) = dim(srcType) - 1 | java/lang/Object. int mergedDim = ELEMENT_OF + ( srcType & DIM_MASK ) ; mergedType = mergedDim | REFERENCE_KIND | symbolTable . addType ( "java/lang/Object" ) ; } } else if ( ( srcType & DIM_MASK ) != 0 || ( srcType & KIND_MASK ) == REFERENCE_KIND ) { // If srcType is any other reference or array type, // merge(srcType, dstType) = min(srcDdim, dstDim) | java/lang/Object // where srcDim is the array dimension of srcType, minus 1 if srcType is an array type // with a non reference element type (and similarly for dstDim). int srcDim = srcType & DIM_MASK ; if ( srcDim != 0 && ( srcType & KIND_MASK ) != REFERENCE_KIND ) { srcDim = ELEMENT_OF + srcDim ; } int dstDim = dstType & DIM_MASK ; if ( dstDim != 0 && ( dstType & KIND_MASK ) != REFERENCE_KIND ) { dstDim = ELEMENT_OF + dstDim ; } mergedType = Math . min ( srcDim , dstDim ) | REFERENCE_KIND | symbolTable . addType ( "java/lang/Object" ) ; } else { // If srcType is any other type, merge(srcType, dstType) = TOP. mergedType = TOP ; } } else if ( dstType == NULL ) { // If dstType is the NULL type, merge(srcType, dstType) = srcType, or TOP if srcType is not a // an array type or a reference type. mergedType = ( srcType & DIM_MASK ) != 0 || ( srcType & KIND_MASK ) == REFERENCE_KIND ? srcType : TOP ; } else { // If dstType is any other type, merge(srcType, dstType) = TOP whatever srcType. mergedType = TOP ; } if ( mergedType != dstType ) { dstTypes [ dstIndex ] = mergedType ; return true ; } return false ; }
Merges the type at the given index in the given abstract type array with the given type.
Returns {@literal true} if the type array has been modified by this operation.

@param symbolTable the type table to use to lookup and store type {@link Symbol}.
@param sourceType the abstract type with which the abstract type array element must be merged.
This type should be of {@link #CONSTANT_KIND}, {@link #REFERENCE_KIND} or {@link
#UNINITIALIZED_KIND} kind, with positive or null array dimensions.
@param dstTypes an array of abstract types. These types should be of {@link #CONSTANT_KIND},
{@link #REFERENCE_KIND} or {@link #UNINITIALIZED_KIND} kind, with positive or null array
dimensions.
@param dstIndex the index of the type that must be merged in dstTypes.
@return {@literal true} if the type array has been modified by this operation.
Merges the type at the given index in the given abstract type array with the given type . Returns { @literal true } if the type array has been modified by this operation .