private static ClassNode parameterizeLowestUpperBound ( final ClassNode lub , final ClassNode a , final ClassNode b , final ClassNode fallback ) { if ( ! lub . isUsingGenerics ( ) ) return lub ; // a common super type exists, all we have to do is to parameterize // it according to the types provided by the two class nodes ClassNode holderForA = findGenericsTypeHolderForClass ( a , lub ) ; ClassNode holderForB = findGenericsTypeHolderForClass ( b , lub ) ; // let's compare their generics type GenericsType [ ] agt = holderForA == null ? null : holderForA . getGenericsTypes ( ) ; GenericsType [ ] bgt = holderForB == null ? null : holderForB . getGenericsTypes ( ) ; if ( agt == null || bgt == null || agt . length != bgt . length ) { return lub ; } GenericsType [ ] lubgt = new GenericsType [ agt . length ] ; for ( int i = 0 ; i < agt . length ; i ++ ) { ClassNode t1 = agt [ i ] . getType ( ) ; ClassNode t2 = bgt [ i ] . getType ( ) ; ClassNode basicType ; if ( areEqualWithGenerics ( t1 , a ) && areEqualWithGenerics ( t2 , b ) ) { // we are facing a self referencing type ! basicType = fallback ; } else { basicType = lowestUpperBound ( t1 , t2 ) ; } if ( t1 . equals ( t2 ) ) { lubgt [ i ] = new GenericsType ( basicType ) ; } else { lubgt [ i ] = GenericsUtils . buildWildcardType ( basicType ) ; } } ClassNode plain = lub . getPlainNodeReference ( ) ; plain . setGenericsTypes ( lubgt ) ; return plain ; }
Given a lowest upper bound computed without generic type information but which requires to be parameterized and the two implementing classnodes which are parameterized with potentially two different types returns a parameterized lowest upper bound .