public MetaClassRegistryImpl(final int loadDefault, final boolean useAccessible) {
    this.useAccessible = useAccessible;

    if (loadDefault == LOAD_DEFAULT) {
      Map<CachedClass, List<MetaMethod>> map = new HashMap<CachedClass, List<MetaMethod>>();

      // let's register the default methods
      registerMethods(null, true, true, map);
      final Class[] additionals = DefaultGroovyMethods.additionals;
      for (int i = 0; i != additionals.length; ++i) {
        createMetaMethodFromClass(map, additionals[i]);
      }

      Class[] pluginDGMs = VMPluginFactory.getPlugin().getPluginDefaultGroovyMethods();
      for (Class plugin : pluginDGMs) {
        registerMethods(plugin, false, true, map);
      }
      registerMethods(DefaultGroovyStaticMethods.class, false, false, map);
      Class[] staticPluginDGMs = VMPluginFactory.getPlugin().getPluginStaticGroovyMethods();
      for (Class plugin : staticPluginDGMs) {
        registerMethods(plugin, false, false, map);
      }

      for (Map.Entry<CachedClass, List<MetaMethod>> e : map.entrySet()) {
        CachedClass cls = e.getKey();
        cls.setNewMopMethods(e.getValue());
      }
    }

    installMetaClassCreationHandle();

    final MetaClass emcMetaClass = metaClassCreationHandle.create(ExpandoMetaClass.class, this);
    emcMetaClass.initialize();
    ClassInfo.getClassInfo(ExpandoMetaClass.class).setStrongMetaClass(emcMetaClass);

    addMetaClassRegistryChangeEventListener(
        new MetaClassRegistryChangeEventListener() {
          public void updateConstantMetaClass(MetaClassRegistryChangeEvent cmcu) {
            synchronized (metaClassInfo) {
              metaClassInfo.add(cmcu.getNewMetaClass());
              DefaultMetaClassInfo.getNewConstantMetaClassVersioning();
              Class c = cmcu.getClassToUpdate();
              DefaultMetaClassInfo.setPrimitiveMeta(c, cmcu.getNewMetaClass() == null);
              Field sdyn;
              try {
                sdyn = c.getDeclaredField(Verifier.STATIC_METACLASS_BOOL);
                sdyn.setBoolean(null, cmcu.getNewMetaClass() != null);
              } catch (Throwable e) {
                // DO NOTHING
              }
            }
          }
        });
  }
示例#2
0
  public MetaMethodIndex(CachedClass theCachedClass) {
    init(DEFAULT_CAPACITY);

    CachedClass last = null;
    if (!theCachedClass.isInterface()) {
      for (CachedClass c = theCachedClass; c != null; c = c.getCachedSuperClass()) {
        final SingleKeyHashMap.Entry e = methodHeaders.getOrPut(c.getTheClass());
        e.value = new Header(c.getTheClass(), last == null ? null : last.getTheClass());
        last = c;
      }
    } else {
      final SingleKeyHashMap.Entry e = methodHeaders.getOrPut(Object.class);
      e.value = new Header(Object.class, theCachedClass.getTheClass());
    }
  }
示例#3
0
  public Object addMethodToList(Object o, MetaMethod method) {
    if (o == null) {
      return method;
    }

    if (o instanceof MetaMethod) {
      MetaMethod match = (MetaMethod) o;
      if (!isMatchingMethod(match, method)) {
        FastArray list = new FastArray(2);
        list.add(match);
        list.add(method);
        return list;
      } else {
        if (match.isPrivate()
            || (!isNonRealMethod(match)
                && match.getDeclaringClass().isInterface()
                && !method.getDeclaringClass().isInterface())) {
          // do not overwrite interface methods with instance methods
          // do not overwrite private methods
          // Note: private methods from parent classes are not shown here,
          // but when doing the multimethod connection step, we overwrite
          // methods of the parent class with methods of a subclass and
          // in that case we want to keep the private methods
        } else {
          CachedClass methodC = method.getDeclaringClass();
          CachedClass matchC = match.getDeclaringClass();
          if (methodC == matchC) {
            if (isNonRealMethod(method)) {
              return method;
            }
          } else if (!methodC.isAssignableFrom(matchC.getTheClass())) {
            return method;
          }
        }
      }
      return o;
    }

    if (o instanceof FastArray) {
      FastArray list = (FastArray) o;
      int found = findMatchingMethod(list, method);

      if (found == -1) {
        list.add(method);
      } else {
        MetaMethod match = (MetaMethod) list.get(found);
        if (match == method) return o;
        if (match.isPrivate()
            || (!isNonRealMethod(match)
                && match.getDeclaringClass().isInterface()
                && !method.getDeclaringClass().isInterface())) {
          // do not overwrite interface methods with instance methods
          // do not overwrite private methods
          // Note: private methods from parent classes are not shown here,
          // but when doing the multimethod connection step, we overwrite
          // methods of the parent class with methods of a subclass and
          // in that case we want to keep the private methods
        } else {
          CachedClass methodC = method.getDeclaringClass();
          CachedClass matchC = match.getDeclaringClass();
          if (methodC == matchC) {
            if (isNonRealMethod(method)) {
              list.set(found, method);
            }
          } else if (!methodC.isAssignableFrom(matchC.getTheClass())) {
            list.set(found, method);
          }
        }
      }
    }

    return o;
  }