uber / motif

A simple DI API for Android / Java
Apache License 2.0
533 stars 43 forks source link

Fix unable to find dependency method #224

Closed idanakav closed 3 years ago

idanakav commented 3 years ago

Context: This is follow up commit to 6a2e7821ae6ffd41e8bae692a00bb498f9c3541b which should fix another edge case of Motif unable to find a dependency method of inner classes types given their full name value in javac is represented with $.

ScopeFactoryImpl is doing a lookup for a method based on the given Type.

The methodByType map is using TreeMap implementation where keys are matched based on Type's compareTo method, if at some point the Type's qualifiedName is mutated the map would not be able to find the key for the given type.

In the edge case the name will be mutated the same way described in 6a2e7821ae6ffd41e8bae692a00bb498f9c3541b.

Fix: The actual fix is done by calling declaredType.asElement().kind which will mutate the fullName property of the type which eventually change the TypeMirror.toString() value.

Below is the stacktrace of such change:

enterClass:612, Symtab (com.sun.tools.javac.code)
enterClass:2630, ClassReader (com.sun.tools.javac.jvm)
readInnerClasses:2729, ClassReader (com.sun.tools.javac.jvm)
read:1120, ClassReader$6 (com.sun.tools.javac.jvm)
readAttrs:1561, ClassReader (com.sun.tools.javac.jvm)
readClassAttrs:1575, ClassReader (com.sun.tools.javac.jvm)
readClass:2681, ClassReader (com.sun.tools.javac.jvm)
readClassBuffer:2775, ClassReader (com.sun.tools.javac.jvm)
readClassFile:2788, ClassReader (com.sun.tools.javac.jvm)
fillIn:348, ClassFinder (com.sun.tools.javac.code)
complete:285, ClassFinder (com.sun.tools.javac.code)
complete:-1, 930579205 (com.sun.tools.javac.code.ClassFinder$$Lambda$1888)
complete:633, Symbol (com.sun.tools.javac.code)
complete:1314, Symbol$ClassSymbol (com.sun.tools.javac.code)
completeEnclosing:322, ClassFinder (com.sun.tools.javac.code)
complete:284, ClassFinder (com.sun.tools.javac.code)
complete:-1, 930579205 (com.sun.tools.javac.code.ClassFinder$$Lambda$1888)
complete:633, Symbol (com.sun.tools.javac.code)
complete:1314, Symbol$ClassSymbol (com.sun.tools.javac.code)
flags:1248, Symbol$ClassSymbol (com.sun.tools.javac.code)
getKind:1381, Symbol$ClassSymbol (com.sun.tools.javac.code)

In order to limit the scope, the if statement is checking for "$" to execute the logic only on inner classes that have not been fully resolved.

tyvsmith commented 3 years ago

Let's create a ticket to audit potential other callsites for this risk and look into broader solutions.