StaticClass getAdapterClass(final ScriptObject classOverrides, final ProtectionDomain protectionDomain) { if(adaptationResult.getOutcome() != AdaptationResult.Outcome.SUCCESS) { throw adaptationResult.typeError(); } return classOverrides == null ? getInstanceAdapterClass(protectionDomain) : getClassAdapterClass(classOverrides, protectionDomain); }
/** * Gathers methods that can be implemented or overridden from the specified type into this factory's * {@link #methodInfos} set. It will add all non-final, non-static methods that are either public or protected from * the type if the type itself is public. If the type is a class, the method will recursively invoke itself for its * superclass and the interfaces it implements, and add further methods that were not directly declared on the * class. * @param type the type defining the methods. */ private void gatherMethods(final Class<?> type) throws AdaptationException { if (Modifier.isPublic(type.getModifiers())) { final Method[] typeMethods = type.isInterface() ? type.getMethods() : type.getDeclaredMethods(); for (final Method typeMethod: typeMethods) { final String name = typeMethod.getName(); if(name.startsWith(SUPER_PREFIX)) { continue; } final int m = typeMethod.getModifiers(); if (Modifier.isStatic(m)) { continue; } if (Modifier.isPublic(m) || Modifier.isProtected(m)) { // Is it a "finalize()"? if(name.equals("finalize") && typeMethod.getParameterCount() == 0) { if(type != Object.class) { hasExplicitFinalizer = true; if(Modifier.isFinal(m)) { // Must be able to override an explicit finalizer throw new AdaptationException(Outcome.ERROR_FINAL_FINALIZER, type.getCanonicalName()); } } continue; } final MethodInfo mi = new MethodInfo(typeMethod); if (Modifier.isFinal(m) || isCallerSensitive(typeMethod)) { finalMethods.add(mi); } else if (!finalMethods.contains(mi) && methodInfos.add(mi)) { if (Modifier.isAbstract(m)) { abstractMethodNames.add(mi.getName()); } mi.setIsCanonical(this); } } } } // If the type is a class, visit its superclasses and declared interfaces. If it's an interface, we're done. // Needing to invoke the method recursively for a non-interface Class object is the consequence of needing to // see all declared protected methods, and Class.getDeclaredMethods() doesn't provide those declared in a // superclass. For interfaces, we used Class.getMethods(), as we're only interested in public ones there, and // getMethods() does provide those declared in a superinterface. if (!type.isInterface()) { final Class<?> superType = type.getSuperclass(); if (superType != null) { gatherMethods(superType); } for (final Class<?> itf: type.getInterfaces()) { gatherMethods(itf); } } }
AdapterInfo(final AdaptationResult.Outcome outcome, final String classList) { this(new AdaptationResult(outcome, classList)); }
boolean isAutoConvertibleFromFunction() { if(adaptationResult.getOutcome() == AdaptationResult.Outcome.ERROR_OTHER) { throw adaptationResult.typeError(); } return autoConvertibleFromFunction; }
/** * Gathers methods that can be implemented or overridden from the specified type into this factory's * {@link #methodInfos} set. It will add all non-final, non-static methods that are either public or protected from * the type if the type itself is public. If the type is a class, the method will recursively invoke itself for its * superclass and the interfaces it implements, and add further methods that were not directly declared on the * class. * @param type the type defining the methods. */ private void gatherMethods(final Class<?> type) throws AdaptationException { if (Modifier.isPublic(type.getModifiers())) { final Method[] typeMethods = type.isInterface() ? type.getMethods() : type.getDeclaredMethods(); for (final Method typeMethod: typeMethods) { final String name = typeMethod.getName(); if(name.startsWith(SUPER_PREFIX)) { continue; } final int m = typeMethod.getModifiers(); if (Modifier.isStatic(m)) { continue; } if (Modifier.isPublic(m) || Modifier.isProtected(m)) { // Is it a "finalize()"? if(name.equals("finalize") && typeMethod.getParameterCount() == 0) { if(type != Object.class) { hasExplicitFinalizer = true; if(Modifier.isFinal(m)) { // Must be able to override an explicit finalizer throw new AdaptationException(Outcome.ERROR_FINAL_FINALIZER, type.getCanonicalName()); } } continue; } final MethodInfo mi = new MethodInfo(typeMethod); if (Modifier.isFinal(m) || isCallerSensitive(typeMethod)) { finalMethods.add(mi); } else if (!finalMethods.contains(mi) && methodInfos.add(mi) && Modifier.isAbstract(m)) { abstractMethodNames.add(mi.getName()); } } } } // If the type is a class, visit its superclasses and declared interfaces. If it's an interface, we're done. // Needing to invoke the method recursively for a non-interface Class object is the consequence of needing to // see all declared protected methods, and Class.getDeclaredMethods() doesn't provide those declared in a // superclass. For interfaces, we used Class.getMethods(), as we're only interested in public ones there, and // getMethods() does provide those declared in a superinterface. if (!type.isInterface()) { final Class<?> superType = type.getSuperclass(); if (superType != null) { gatherMethods(superType); } for (final Class<?> itf: type.getInterfaces()) { gatherMethods(itf); } } }
/** * Gathers methods that can be implemented or overridden from the specified type into this factory's * {@link #methodInfos} set. It will add all non-final, non-static methods that are either public or protected from * the type if the type itself is public. If the type is a class, the method will recursively invoke itself for its * superclass and the interfaces it implements, and add further methods that were not directly declared on the * class. * @param type the type defining the methods. */ private void gatherMethods(final Class<?> type) throws AdaptationException { if (Modifier.isPublic(type.getModifiers())) { final Module module = type.getModule(); if (module != null) { accessedModules.add(module); } final Method[] typeMethods = type.isInterface() ? type.getMethods() : type.getDeclaredMethods(); for (final Method typeMethod: typeMethods) { final String name = typeMethod.getName(); if(name.startsWith(SUPER_PREFIX)) { continue; } final int m = typeMethod.getModifiers(); if (Modifier.isStatic(m)) { continue; } if (Modifier.isPublic(m) || Modifier.isProtected(m)) { // Is it a "finalize()"? if(name.equals("finalize") && typeMethod.getParameterCount() == 0) { if(type != Object.class) { hasExplicitFinalizer = true; if(Modifier.isFinal(m)) { // Must be able to override an explicit finalizer throw new AdaptationException(Outcome.ERROR_FINAL_FINALIZER, type.getCanonicalName()); } } continue; } for (final Class<?> pt : typeMethod.getParameterTypes()) { if (pt.isPrimitive()) continue; final Module ptMod = pt.getModule(); if (ptMod != null) { accessedModules.add(ptMod); } } final Class<?> rt = typeMethod.getReturnType(); if (!rt.isPrimitive()) { final Module rtMod = rt.getModule(); if (rtMod != null) accessedModules.add(rtMod); } final MethodInfo mi = new MethodInfo(typeMethod); if (Modifier.isFinal(m) || isCallerSensitive(typeMethod)) { finalMethods.add(mi); } else if (!finalMethods.contains(mi) && methodInfos.add(mi) && Modifier.isAbstract(m)) { abstractMethodNames.add(mi.getName()); } } } } // If the type is a class, visit its superclasses and declared interfaces. If it's an interface, we're done. // Needing to invoke the method recursively for a non-interface Class object is the consequence of needing to // see all declared protected methods, and Class.getDeclaredMethods() doesn't provide those declared in a // superclass. For interfaces, we used Class.getMethods(), as we're only interested in public ones there, and // getMethods() does provide those declared in a superinterface. if (!type.isInterface()) { final Class<?> superType = type.getSuperclass(); if (superType != null) { gatherMethods(superType); } for (final Class<?> itf: type.getInterfaces()) { gatherMethods(itf); } } }
/** * Choose between the passed class loader and the class loader that defines the * ScriptObject class, based on which of the two can see the classes in both. * * @param classAndLoader the loader and a representative class from it that will * be used to add the generated adapter to its ADAPTER_INFO_MAPS. * * @return the class loader that sees both the specified class and Nashorn classes. * * @throws IllegalStateException if no such class loader is found. */ private static ClassLoader findCommonLoader(final ClassAndLoader classAndLoader) throws AdaptationException { if(classAndLoader.canSee(SCRIPT_OBJECT_LOADER)) { return classAndLoader.getLoader(); } if (SCRIPT_OBJECT_LOADER.canSee(classAndLoader)) { return SCRIPT_OBJECT_LOADER.getLoader(); } throw new AdaptationException(AdaptationResult.Outcome.ERROR_NO_COMMON_LOADER, classAndLoader.getRepresentativeClass().getCanonicalName()); }