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()); } }
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; }