Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  package org.dynjs.runtime.linker.java.jsimpl;
  
 
 import java.util.*;
 
 import static me.qmx.jitescript.util.CodegenUtils.*;
 
 public class JSJavaImplementationManager {
 
     private static AtomicInteger counter = new AtomicInteger();
 
     private Map<Class<?>, Class<?>> implementations = new HashMap<>();
 
 
     private ShadowObjectLinker shadowLinker;
 
     public JSJavaImplementationManager(ShadowObjectLinker shadowLinker) {
         this. = shadowLinker;
     }
 
     public Object getImplementationWrapper(Class<?> targetClassExecutionContext contextJSObject implementationthrows Exception {
         Class<?> implClass = getImplementationWrapper(targetClasscontext.getClassLoader());
 
         Constructor<?> ctor = implClass.getConstructor(ExecutionContext.classJSObject.class);
 
         JSObject shadow = createShadow(contextimplClassimplementation);
 
         Object implInstance = ctor.newInstance(contextimplementation);
 
         if (shadow != null) {
             this..putShadowObject(implInstanceshadow);
         }
 
         return implInstance;
     }
 
     protected JSObject createShadow(ExecutionContext contextClass<?> implClassJSObject implementation) {
         DynObject shadow = new DynObject(context.getGlobalContext());
         Method[] methods = implClass.getDeclaredMethods();
         
         boolean shadowed = false;
 
         List<StringpropNames = implementation.getOwnPropertyNames().toList();
         props: for (String propName : propNames) {
             for (Method m : methods) {
                 if (m.getName().equals(propName)) {
                     continue props;
                 }
             }
             Object val = implementation.get(contextpropName);
             if (val instanceof JSFunction) {
                 shadowed = true;
                 shadow.put(propNameval);
                 implementation.delete(contextpropNamefalse);
             }
         }
         if (shadowed) {
             return shadow;
         }
 
         return null;
     }
 
     public Class<?> getImplementationWrapper(Class<?> targetClassDynamicClassLoader classLoader) {
         Class<?> implClass = this..get(targetClass);
         if (implClass == null) {
             implClass = createImplementationWrapper(targetClassclassLoader);
             this..put(targetClassimplClass);
         }
 
         return implClass;
     }
 
     private Class<?> createImplementationWrapper(Class<?> targetClassDynamicClassLoader classLoader) {
         final String className = "org/dynjs/gen/impl/" + targetClass.getSimpleName() + "JS_" + .getAndIncrement();
 
         final Class<?> superClass = (targetClass.isInterface() ? Object.class : targetClass);
         final String superClassName = p(superClass);
         String[] interfaces = null;
 
         if (targetClass.isInterface()) {
             interfaces = new String[] { p(targetClass) };
         } else {
             interfaces = new String[] {};
         }
 
        JiteClass jiteClass = new JiteClass(classNamesuperClassNameinterfaces);
        jiteClass.defineField("context".ci(ExecutionContext.class), null);
        jiteClass.defineField("implementation".ci(JSObject.class), null);
        CodeBlock codeBlock = new CodeBlock()
            .aload(.)
             // this
            .invokespecial(superClassName"<init>"sig(void.class))
             // <empty>
            .aload(.)
             // this
            .aload(1)
             // this context
            .putfield(className.replace('.''/'), "context"ci(ExecutionContext.class))
             // <empty>
            .aload(.)
             // this
            .aload(2)
             // this JSObject
            .putfield(className.replace('.''/'), "implementation"ci(JSObject.class))
             // <empty>
            .aload(2)
             // JSObject
            .voidreturn();
        jiteClass.defineMethod("<init>".sig(void.classExecutionContext.classJSObject.class), codeBlock);
        defineMethods(targetClassjiteClasssuperClass);
        byte[] bytecode = jiteClass.toBytes(.);
        return classLoader.define(jiteClass.getClassName().replace('/''.'), bytecode);
    }
    private void defineMethods(Class<?> targetClassJiteClass jiteClassClass<?> superClass) {
        for (Method method:  getMethods(targetClass)) {
            int modifiers = method.getModifiers();
            if ((Modifier.isPublic(modifiers) || Modifier.isProtected(modifiers)) && 
                    !Modifier.isStatic(modifiers) && !Modifier.isFinal(modifiers)) {
                defineMethod(methodjiteClasssuperClass);
            }
        }
    }
    private void defineMethod(final Method methodfinal JiteClass jiteClassfinal Class<?> superClass) {
        .defineMethod(methodjiteClasssuperClass);
    }
    
    private List<MethodgetMethods(Class<?> targetClass) {
        List<Methodmethods = new LinkedList<Method>();
        methods.addAll(Arrays.asList(targetClass.getMethods()));
        
        return addProtectedMethods(targetClassmethods);
    }
    private List<MethodaddProtectedMethods(Class<?> targetClassList<Methodmethods) {
        if (targetClass != null && !targetClass.equals(Object.class)) {
            List<MethoddeclaredMethods = Collections.unmodifiableList(methods);
            
            for (Method method : targetClass.getDeclaredMethods()) {
                if (Modifier.isProtected(method.getModifiers()) && !alreadyDeclaredMethod(methoddeclaredMethods)) {
                    methods.add(method);
                }
            }
            
            addProtectedMethods(targetClass.getSuperclass(), methods);            
        }
        return methods;
    }
    
    private boolean alreadyDeclaredMethod(Method methodList<MethoddeclaredMethods) {
        Class<?>[] parameterTypes = method.getParameterTypes();
        for (Method declaredMethod : declaredMethods) {
            if (method.getName().equals(declaredMethod.getName()) &&
                    Arrays.equals(parameterTypesdeclaredMethod.getParameterTypes())) {
                return true;
            }
        }
        return false;
    }
New to GrepCode? Check out our FAQ X