Not logged in.  Login/Logout/Register | List snippets | | Create snippet | Upload image | Upload data

73
LINES

< > BotCompany Repo | #1018496 // _MethodCache - caches methods of a class

JavaX fragment (include) [tags: use-pretranspiled]

Libraryless. Click here for Pure Java version (7633L/43K).

// immutable, has strong refs
// Do not run in a synchronized block - it goes wrong in the presence
// of elaborate classloaders (like in Gazelle BEA)
// see #1102990 and #1102991

final sclass _MethodCache {
  final Class c;
  final HashMap<S, L<Method>> cache = new HashMap;
  
  *(Class *c) { _init(); }
  
  void _init() {
    Class _c = c;
    java.lang.Module myModule = getClass().getModule();
    bool anyHiddenClasses;
    
    while (_c != null) {
      bool exported = classIsExportedTo(_c, myModule);
      printVars ifdef _MethodCache_debug("_MethodCache._init", +_c, +exported);
      
      if (!exported)
        set anyHiddenClasses;
      else
        for (Method m : _c.getDeclaredMethods())
          if ((anyHiddenClasses || !isAbstract(m))
            && !reflection_isForbiddenMethod(m))
            multiMapPut(cache, m.getName(), makeAccessible(m));

      _c = _c.getSuperclass();
    }
    
    // add default methods - this might lead to a duplication
    // because the overridden method is also added, but it's not
    // a problem except for minimal performance loss.
    // If any classes in the hierarchy were inaccessible, we add
    // all interface methods (see test_callForbiddenMethodByReflection for a test)
    
    for (Class intf : allInterfacesImplementedBy(c))
      for (Method m : intf.getDeclaredMethods())
        if ((anyHiddenClasses || m.isDefault()) && !reflection_isForbiddenMethod(m))
          multiMapPut(cache, m.getName(), makeAccessible(m));

    print ifdef _MethodCache_debug("MethodCache " + this + ": " + className(c) + " => " + keys(cache));
  }
  
  // Returns only matching methods
  Method findMethod(S method, O[] args) ctex {
    L<Method> m = cache.get(method);
    print ifdef _MethodCache_debug("findMethod " + this + ": " + className(c) + "/" + method + " => " + m);
    if (m == null) null;
    int n = m.size();
    for i to n: {
      Method me = m.get(i);
      if (call_checkArgs(me, args, false))
        ret me;
    }
    null;
  }
  
  Method findStaticMethod(S method, O[] args) ctex {
    L<Method> m = cache.get(method);
    if (m == null) null;
    int n = m.size();
    for i to n: {
      Method me = m.get(i);
      if (isStaticMethod(me) && call_checkArgs(me, args, false))
        ret me;
    }
    null;
  }
  
  //Cl<Method> allMethods() { ret allValues(cache); }
}

Author comment

Began life as a copy of #1005370

download  show line numbers  debug dex  old transpilations   

Travelled to 16 computer(s): aoiabmzegqzx, bhatertpkbcr, cbybwowwnfue, cfunsshuasjs, gwrvuhgaqvyk, irmadwmeruwu, ishqpsrjomds, jcllbfdqhrgy, lpdgvwnxivlt, mqqgnosmbjvj, onxytkatvevr, pyentgdyhuwx, pzhvpgtvlbxg, tvejysmllsmz, vouqrxazstgt, xrpafgyirdlv

No comments. add comment

Snippet ID: #1018496
Snippet name: _MethodCache - caches methods of a class
Eternal ID of this version: #1018496/29
Text MD5: ca089a15a737d1f1a5ee6074d102fd52
Transpilation MD5: 679aa3a130c44e61f8c248153f03b879
Author: stefan
Category: javax
Type: JavaX fragment (include)
Public (visible to everyone): Yes
Archived (hidden from active list): No
Created/modified: 2022-03-08 06:19:22
Source code size: 2429 bytes / 73 lines
Pitched / IR pitched: No / No
Views / Downloads: 405 / 1142
Version history: 28 change(s)
Referenced in: #1034167 - Standard Classes + Interfaces (LIVE, continuation of #1003674)
#1034186 - _MethodCache - caches methods of a class [backup before Java 9 fix]