691
692 /*
693 * Verify that this interface is not a duplicate.
694 */
695 if (interfaceSet.put(intf, Boolean.TRUE) != null) {
696 throw new IllegalArgumentException("repeated interface: " + intf.getName());
697 }
698 }
699
700 for (Class<?> type : refTypes) {
701 ensureVisible(loader, type);
702 }
703 }
704
705 /*
706 * Returns all types referenced by all public non-static method signatures of
707 * the proxy interfaces
708 */
709 private static Set<Class<?>> referencedTypes(ClassLoader loader,
710 List<Class<?>> interfaces) {
711 return interfaces.stream()
712 .flatMap(intf -> Stream.of(intf.getMethods())
713 .filter(m -> !Modifier.isStatic(m.getModifiers()))
714 .flatMap(ProxyBuilder::methodRefTypes)
715 .map(ProxyBuilder::getElementType)
716 .filter(t -> !t.isPrimitive()))
717 .collect(Collectors.toSet());
718 }
719
720 /*
721 * Extracts all types referenced on a method signature including
722 * its return type, parameter types, and exception types.
723 */
724 private static Stream<Class<?>> methodRefTypes(Method m) {
725 return Stream.of(new Class<?>[] { m.getReturnType() },
726 m.getParameterTypes(),
727 m.getExceptionTypes())
728 .flatMap(Stream::of);
729 }
730
731 /**
732 * Returns the module that the generated proxy class belongs to.
733 *
734 * If all proxy interfaces are public and in exported packages,
735 * then the proxy class is in unnamed module.
736 *
737 * If any of proxy interface is package-private, then the proxy class
738 * is in the same module of the package-private interface.
739 *
740 * If all proxy interfaces are public and at least one in a non-exported
741 * package, then the proxy class is in a dynamic module in a
742 * non-exported package. Reads edge and qualified exports are added
743 * for dynamic module to access.
744 */
745 private static Module mapToModule(ClassLoader loader,
746 List<Class<?>> interfaces,
747 Set<Class<?>> refTypes) {
748 Map<Class<?>, Module> modulePrivateTypes = new HashMap<>();
|
691
692 /*
693 * Verify that this interface is not a duplicate.
694 */
695 if (interfaceSet.put(intf, Boolean.TRUE) != null) {
696 throw new IllegalArgumentException("repeated interface: " + intf.getName());
697 }
698 }
699
700 for (Class<?> type : refTypes) {
701 ensureVisible(loader, type);
702 }
703 }
704
705 /*
706 * Returns all types referenced by all public non-static method signatures of
707 * the proxy interfaces
708 */
709 private static Set<Class<?>> referencedTypes(ClassLoader loader,
710 List<Class<?>> interfaces) {
711 var types = new HashSet<Class<?>>();
712 for (var intf : interfaces) {
713 for (Method m : intf.getMethods()) {
714 if (!Modifier.isStatic(m.getModifiers())) {
715 addElementType(types, m.getReturnType());
716 addElementTypes(types, m.getSharedParameterTypes());
717 addElementTypes(types, m.getSharedExceptionTypes());
718 }
719 }
720 }
721 return types;
722 }
723
724 private static void addElementTypes(HashSet<Class<?>> types,
725 Class<?> ... classes) {
726 for (var cls : classes) {
727 addElementType(types, cls);
728 }
729 }
730
731 private static void addElementType(HashSet<Class<?>> types,
732 Class<?> cls) {
733 var type = getElementType(cls);
734 if (!type.isPrimitive()) {
735 types.add(type);
736 }
737 }
738
739 /**
740 * Returns the module that the generated proxy class belongs to.
741 *
742 * If all proxy interfaces are public and in exported packages,
743 * then the proxy class is in unnamed module.
744 *
745 * If any of proxy interface is package-private, then the proxy class
746 * is in the same module of the package-private interface.
747 *
748 * If all proxy interfaces are public and at least one in a non-exported
749 * package, then the proxy class is in a dynamic module in a
750 * non-exported package. Reads edge and qualified exports are added
751 * for dynamic module to access.
752 */
753 private static Module mapToModule(ClassLoader loader,
754 List<Class<?>> interfaces,
755 Set<Class<?>> refTypes) {
756 Map<Class<?>, Module> modulePrivateTypes = new HashMap<>();
|