private List<Tuple2<IJavaModuleData, ClassInfo>> getAllKnownSubclasses(ModuleJandexIndex module, DotName name, boolean isInterface) { ImmutableList.Builder<Tuple2<IJavaModuleData, ClassInfo>> builder = ImmutableList.builder(); IndexView indexView = module.getIndex().get(); if (indexView != null) { Collection<ClassInfo> subTypes = isInterface ? indexView.getAllKnownImplementors(name) : indexView.getAllKnownSubclasses(name); if (subTypes != null) { for (ClassInfo info : subTypes) { builder.add(Tuples.of(module, info)); } } } return builder.build(); }
/** * Extract the package information from the given {@code ClassInfo} object. * * @param classInfo the class metadata. * @param packages the collection to which we need to add the package information. */ private static void extractAndAddPackageInfo(ClassInfo classInfo, Set<String> packages, IndexView indexView) { if (classInfo == null) { return; } // Check if we were given an abstract class / interface, in which case we need to check the IndexView to see if there // is an implementation or not. String className = classInfo.name().toString(); if (indexView != null) { DotName dotName = DotName.createSimple(className); if (Modifier.isInterface(classInfo.flags())) { indexView.getAllKnownImplementors(dotName).forEach(ci -> extractAndAddPackageInfo(ci, packages, indexView)); } else if (Modifier.isAbstract(classInfo.flags())) { indexView.getAllKnownSubclasses(dotName).forEach(ci -> extractAndAddPackageInfo(ci, packages, indexView)); } } StringBuilder builder = new StringBuilder(className).reverse(); int idx = builder.indexOf("."); if (idx != -1) { builder.delete(0, idx + 1); } packages.add(builder.reverse().toString()); }