@@ -87,13 +87,20 @@ object DexClassModelAdapter {
8787 * degrade to shells at the repeated key (resolving-stack cycle guard).
8888 * Super/interface edges stay name-only references in both modes.
8989 */
90+ private val javaClassTypeMemo = java.util.concurrent.ConcurrentHashMap <String , JavaClassType >()
91+
9092 fun toJavaClassType (cls : DexClass , dexClasses : Collection <DexClass > = emptyList()): JavaClassType {
91- return javaClassTypeFor(
92- cls = cls,
93- dexByName = dexClasses.associateBy(DexClass ::binaryName),
94- resolving = emptySet(),
95- referenceDepth = 0
96- )
93+ // Memoize per (class, dex-set identity): surface building walks the dex
94+ // parent chain and costs seconds on-device for framework classes.
95+ val key = cls.binaryName + " #" + System .identityHashCode(dexClasses)
96+ return javaClassTypeMemo.computeIfAbsent(key) {
97+ javaClassTypeFor(
98+ cls = cls,
99+ dexByName = dexClasses.associateBy(DexClass ::binaryName),
100+ resolving = emptySet(),
101+ referenceDepth = 0
102+ )
103+ }
97104 }
98105
99106 /* *
@@ -102,21 +109,22 @@ object DexClassModelAdapter {
102109 * completion/hover over a dex-typed value re-requests the same class. Keyed
103110 * by binary name; surfaces are immutable so sharing is safe.
104111 */
105- private val moduleTypeByBinaryName = java.util.concurrent.ConcurrentHashMap <String , ModuleType >()
106-
107112 fun cachedModuleType (cls : DexClass , dexClasses : Collection <DexClass >): ModuleType =
108- moduleTypeByBinaryName.computeIfAbsent(cls.binaryName) {
109- toModuleType(cls, dexClasses)
110- }
113+ toModuleType(cls, dexClasses)
111114
112115 /* *
113116 * Adapt one dex class into the provider-shaped module table:
114117 * `__class` (instance shell), `__call` (when constructors exist), public
115118 * static field values, static method overloads, and direct inner classes
116119 * from [dexClasses] keyed by simple name (depth-1 policy).
117120 */
121+ private val moduleTypeMemo = java.util.concurrent.ConcurrentHashMap <String , ModuleType >()
122+
118123 fun toModuleType (cls : DexClass , dexClasses : Collection <DexClass > = emptyList()): ModuleType {
119- return toModuleType(cls, dexClasses.associateBy(DexClass ::binaryName), innerClassDepth = 0 )
124+ val key = cls.binaryName + " #" + System .identityHashCode(dexClasses)
125+ return moduleTypeMemo.computeIfAbsent(key) {
126+ toModuleType(cls, dexClasses.associateBy(DexClass ::binaryName), innerClassDepth = 0 )
127+ }
120128 }
121129
122130 /* *
0 commit comments