public static ClassNode lowestUpperBound ( ClassNode a , ClassNode b ) { ClassNode lub = lowestUpperBound ( a , b , null , null ) ; if ( lub == null || ! lub . isUsingGenerics ( ) ) return lub ; // types may be parameterized. If so, we must ensure that generic type arguments // are made compatible if ( lub instanceof LowestUpperBoundClassNode ) { // no parent super class representing both types could be found // or both class nodes implement common interfaces which may have // been parameterized differently. // We must create a classnode for which the "superclass" is potentially parameterized // plus the interfaces ClassNode superClass = lub . getSuperClass ( ) ; ClassNode psc = superClass . isUsingGenerics ( ) ? parameterizeLowestUpperBound ( superClass , a , b , lub ) : superClass ; ClassNode [ ] interfaces = lub . getInterfaces ( ) ; ClassNode [ ] pinterfaces = new ClassNode [ interfaces . length ] ; for ( int i = 0 , interfacesLength = interfaces . length ; i < interfacesLength ; i ++ ) { final ClassNode icn = interfaces [ i ] ; if ( icn . isUsingGenerics ( ) ) { pinterfaces [ i ] = parameterizeLowestUpperBound ( icn , a , b , lub ) ; } else { pinterfaces [ i ] = icn ; } } return new LowestUpperBoundClassNode ( ( ( LowestUpperBoundClassNode ) lub ) . name , psc , pinterfaces ) ; } else { return parameterizeLowestUpperBound ( lub , a , b , lub ) ; } }
Given two class nodes returns the first common supertype or the class itself if there are equal . For example Double and Float would return Number while Set and String would return Object .