Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
   * Copyright 2003-2007 the original author or authors.
   *
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   *
   *     http://www.apache.org/licenses/LICENSE-2.0
   *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
 package org.codehaus.groovy.runtime.metaclass;
 
 
 
 public class MetaMethodIndex {
     public SingleKeyHashMap methodHeaders = new SingleKeyHashMap();
 
     public static class Header {
         public Entry head;
         Class cls;
         public int clsHashCode31;
         public Class subclass;
 
         public Header(Class cls) {
             this (clsnull);
         }
 
         public Header(Class clsClass subclass) {
             this. = cls;
             this. = subclass;
             this. = 31 * cls.hashCode();
         }
     }
 
     public static class CacheEntry {
         public Class [] params;
         public MetaMethod method;
     }
 
     public static class Entry {
         public int hash;
 
         public Entry nextHashEntrynextClassEntry;
 
         public String name;
         public Class cls;
 
         public Object methodsmethodsForSuperstaticMethods;
 
 
         public String toString () {
             return "[" +  + ", " + .getName() + "]";
         }
     }
 
     public MetaMethodIndex(CachedClass theCachedClass) {
         init();
 
         CachedClass last = null;
         if (!theCachedClass.isInterface()) {
             for (CachedClass c = theCachedClassc != nullc = c.getCachedSuperClass()) {
               final SingleKeyHashMap.Entry e = .getOrPut(c.getTheClass());
               e.value = new Header (c.getTheClass(), last == null ? null : last.getTheClass());
               last = c;
             }
         }
         else {
             final SingleKeyHashMap.Entry e = .getOrPut(Object.class);
             e.value = new Header (Object.classtheCachedClass.getTheClass());
         }
     }
 
     protected Entry table[];
 
     protected static final int DEFAULT_CAPACITY = 32;
     protected static final int MINIMUM_CAPACITY = 4;
     protected static final int MAXIMUM_CAPACITY = 1 << 28;
 
     protected int size;
     protected transient int threshold;
 
     public static int hash(int h) {
         h += ~(h << 9);
         h ^= (h >>> 14);
         h += (h << 4);
         h ^= (h >>> 10);
         return h;
    }
    public int size() {
        return ;
    }
    public boolean isEmpty() {
        return  == 0;
    }
    public void clear() {
        Object[] tab = ;
        for (int i = 0; i < tab.lengthi++)
            tab[i] = null;
         = 0;
    }
    public void init(int initCapacity) {
         = (initCapacity * 6) / 8;
         = new Entry[initCapacity];
    }
    public void resize(int newLength) {
        Entry[] oldTable = ;
        int oldLength = .;
        Entry[] newTable = new Entry[newLength];
        for (int j = 0; j < oldLengthj++) {
            for (Entry e = oldTable[j]; e != null;) {
                Entry next = e.nextHashEntry;
                int index = e.hash & (newLength - 1);
                e.nextHashEntry = newTable[index];
                newTable[index] = e;
                e = next;
            }
        }
         = newTable;
         = (6 * newLength) / 8;
    }
    public interface EntryIterator {
        boolean hasNext();
        Entry next();
    }
    public Entry[] getTable() {
        return ;
    }
        return new EntryIterator() {
            Entry next;    // next entry to return
            int index;        // current slot
            Entry current;    // current entry
            {
                Entry[] t = ;
                int i = t.length;
                Entry n = null;
                if ( != 0) { // advance to first entry
                    while (i > 0 && (n = t[--i]) == null) {
                    }
                }
                 = n;
                 = i;
            }
            public boolean hasNext() {
                return  != null;
            }
            public Entry next() {
                return nextEntry();
            }
            Entry nextEntry() {
                Entry e = ;
                if (e == null)
                    throw new NoSuchElementException();
                Entry n = e.nextHashEntry;
                Entry[] t = ;
                int i = ;
                while (n == null && i > 0)
                    n = t[--i];
                 = i;
                 = n;
                return  = e;
            }
        };
    }
    public final Entry getMethods(Class clsString name) {
        int h = hash(31 * cls.hashCode() + name.hashCode());
        Entry e = [h & (. - 1)];
        for (; e != nulle = e.nextHashEntry)
            if (e.hash == h && cls == e.cls && (e.name == name || e.name.equals(name)) )
                return e;
        return null;
    }
    public Entry getOrPutMethods(String nameHeader header) {
        final Class cls = header.cls;
        int h = hash(header.clsHashCode31 + name.hashCode());
        final Entry[] t = ;
        final int index = h & (t.length - 1);
        Entry e = t[index];
        for (; e != nulle = e.nextHashEntry)
            if (e.hash == h && cls == e.cls && (e.name == name || e.name.equals(name)) )
                return e;
        Entry entry = new Entry();
        entry.nextHashEntry = t[index];
        entry.hash = h;
        entry.name = name.intern();
        entry.cls = cls;
        t[index] = entry;
        entry.nextClassEntry = header.head;
        header.head = entry;
        if (++ == )
            resize(2 * t.length);
        return entry;
    }
    public Header getHeader(Class cls) {
        Header header;
        final SingleKeyHashMap.Entry head = .getOrPut(cls);
        if (head.value == null) {
            head.value = new Header(cls);
        }
        header = (Headerhead.value;
        return header;
    }
    public void copyNonPrivateMethods(Class fromClass to) {
        copyNonPrivateMethods(getHeader(from), getHeader(to));
    }
    public void copyNonPrivateMethods(Header fromHeader to) {
        for (Entry e = from.heade != nulle = e.nextClassEntry)
            copyNonPrivateMethods(eto);
    }
    public void copyAllMethodsToSuper(Header fromHeader to) {
        for (Entry e = from.heade != nulle = e.nextClassEntry)
            copyAllMethodsToSuper(eto);
    }
    public void copyNonPrivateMethodsFromSuper(Header from) {
        for (Entry e = from.heade != nulle = e.nextClassEntry)
            copyNonPrivateMethodsFromSuper(e);
    }
    private void copyNonPrivateMethods(Entry fromHeader to) {
        Object oldListOrMethod = from.methods;
        if (oldListOrMethod instanceof FastArray) {
            FastArray oldList = (FastArrayoldListOrMethod;
            Entry e = null;
            int len1 = oldList.size();
            Object list[] = oldList.getArray();
            for (int j = 0; j != len1; ++j) {
                MetaMethod method = (MetaMethodlist[j];
                if (method.isPrivate()) continue;
                if (e == null)
                    e = getOrPutMethods(from.nameto);
                e.methods = addMethodToList(e.methodsmethod);
            }
        } else {
            MetaMethod method = (MetaMethodoldListOrMethod;
            if (!method.isPrivate()) {
                Entry e = getOrPutMethods(from.nameto);
                e.methods = addMethodToList(e.methodsmethod);
            }
        }
    }
    private void copyAllMethodsToSuper(Entry fromHeader to) {
        Object oldListOrMethod = from.methods;
        if (oldListOrMethod instanceof FastArray) {
            FastArray oldList = (FastArrayoldListOrMethod;
            Entry e = null;
            int len1 = oldList.size();
            Object list[] = oldList.getArray();
            for (int j = 0; j != len1; ++j) {
                MetaMethod method = (MetaMethodlist[j];
                if (e == null)
                    e = getOrPutMethods(from.nameto);
                e.methodsForSuper = addMethodToList(e.methodsForSupermethod);
            }
        } else {
            MetaMethod method = (MetaMethodoldListOrMethod;
            Entry e = getOrPutMethods(from.nameto);
            e.methodsForSuper = addMethodToList(e.methodsForSupermethod);
        }
    }
    private void copyNonPrivateMethodsFromSuper(Entry e) {
        Object oldListOrMethod = e.methodsForSuper;
        if (oldListOrMethod == null)
          return;
        
        if (oldListOrMethod instanceof FastArray) {
            FastArray oldList = (FastArrayoldListOrMethod;
            int len1 = oldList.size();
            Object list[] = oldList.getArray();
            for (int j = 0; j != len1; ++j) {
                MetaMethod method = (MetaMethodlist[j];
                if (method.isPrivate()) continue;
                e.methods = addMethodToList(e.methodsmethod);
            }
        } else {
            MetaMethod method = (MetaMethodoldListOrMethod;
            if (!method.isPrivate()) {
                e.methods = addMethodToList(e.methodsmethod);
            }
        }
    }
    public void copyNonPrivateMethodsDown(Class fromClass to) {
    }
    public void copyNonPrivateNonNewMetaMethods(Header fromHeader to) {
        for (Entry e = from.heade != nulle = e.nextClassEntry)
            copyNonPrivateNonNewMetaMethods(eto);
    }
    private void copyNonPrivateNonNewMetaMethods(Entry fromHeader to) {
        Object oldListOrMethod = from.methods;
        if (oldListOrMethod == null)
          return;
        
        if (oldListOrMethod instanceof FastArray) {
            FastArray oldList = (FastArrayoldListOrMethod;
            Entry e = null;
            int len1 = oldList.size();
            Object list[] = oldList.getArray();
            for (int j = 0; j != len1; ++j) {
                MetaMethod method = (MetaMethodlist[j];
                if (method instanceof NewMetaMethod || method.isPrivate()) continue;
                if (e == null)
                    e = getOrPutMethods(from.nameto);
                e.methods = addMethodToList(e.methodsmethod);
            }
        } else {
            MetaMethod method = (MetaMethodoldListOrMethod;
            if (method instanceof NewMetaMethod || method.isPrivate()) return;
            Entry e = getOrPutMethods(from.nameto);
            e.methods = addMethodToList(e.methodsmethod);
        }
    }
    public Object addMethodToList(Object oMetaMethod method) {
        if (o == null) {
            return method;
        }
        if (o instanceof MetaMethod) {
            MetaMethod match = (MetaMethodo;
            if (!isMatchingMethod(matchmethod)) {
                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 = (FastArrayo;
            int found = findMatchingMethod(listmethod);
            if (found == -1) {
                list.add(method);
            } else {
                MetaMethod match = (MetaMethodlist.get(found);
                if (match==methodreturn 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(foundmethod);
                        }
                    } else if (!methodC.isAssignableFrom(matchC.getTheClass())) {
                        list.set(foundmethod);
                    }
                }
            }
        }
        return o;
    }
    private boolean isNonRealMethod(MetaMethod method) {
        return method instanceof NewInstanceMetaMethod ||
                method instanceof NewStaticMetaMethod ||
                method instanceof ClosureMetaMethod ||
                method instanceof GeneratedMetaMethod ||
                method instanceof ClosureStaticMetaMethod ||
                method instanceof MixinInstanceMetaMethod;
    }
    private boolean isMatchingMethod(MetaMethod aMethodMetaMethod method) {
        if (aMethod==methodreturn true;
        CachedClass[] params1 = aMethod.getParameterTypes();
        CachedClass[] params2 = method.getParameterTypes();
        if (params1.length != params2.length) {
            return false;
        }
        boolean matches = true;
        for (int i = 0; i < params1.lengthi++) {
            if (params1[i] != params2[i]) {
                matches = false;
                break;
            }
        }
        return matches;
    }
    private int findMatchingMethod(FastArray listMetaMethod method) {
        int len = list.size();
        Object data[] = list.getArray();
        for (int j = 0; j != len; ++j) {
            MetaMethod aMethod = (MetaMethoddata[j];
            if (isMatchingMethod(aMethodmethod))
                return j;
        }
        return -1;
    }
    public void copyMethodsToSuper() {
        Entry[] table = this.;
        int length = table.length;
        for (int j = 0; j < lengthj++) {
            for (Entry e = table[j]; e != nulle = e.nextHashEntry) {
                if (e.methods instanceof FastArray)
                    e.methodsForSuper = ((FastArraye.methods).copy();
                else
                    e.methodsForSuper = e.methods;
            }
        }
    }
    public void copy(Class cHeader index) {
        copy(getHeader(c), index);
    }
    public void copy(Header fromHeader to) {
        for (Entry e = from.heade != nulle = e.nextClassEntry)
            copyAllMethods(eto);
    }
    private void copyAllMethods(Entry fromHeader to) {
        Object oldListOrMethod = from.methods;
        if (oldListOrMethod instanceof FastArray) {
            FastArray oldList = (FastArrayoldListOrMethod;
            Entry e = null;
            int len1 = oldList.size();
            Object list[] = oldList.getArray();
            for (int j = 0; j != len1; ++j) {
                MetaMethod method = (MetaMethodlist[j];
                if (e == null)
                    e = getOrPutMethods(from.nameto);
                e.methods = addMethodToList(e.methodsmethod);
            }
        } else {
            MetaMethod method = (MetaMethodoldListOrMethod;
            if (!method.isPrivate()) {
                Entry e = getOrPutMethods(from.nameto);
                e.methods = addMethodToList(e.methodsmethod);
            }
        }
    }
    public void clearCaches() {
        for (int i = 0; i != .; ++i )
          for (Entry e =  [i]; e != nulle = e.nextHashEntry ) {
              e.cachedMethod = e.cachedMethodForSuper = e.cachedStaticMethod = null;
          }
    }
    public void clearCaches(String name) {
        for (int i = 0; i != .; ++i )
          for (Entry e =  [i]; e != nulle = e.nextHashEntry ) {
              if (e.name.equals(name)) {
                  e.cachedMethod = e.cachedMethodForSuper = e.cachedStaticMethod = null;
              }
          }
    }
New to GrepCode? Check out our FAQ X