Closed pshirshov closed 6 years ago
Static bindings can already bind class inner and object inner types, but not function inner types. see: https://github.com/pshirshov/izumi-r2/blob/develop/distage/distage-static/src/test/scala/com/github/pshirshov/izumi/distage/StaticInjectorTest.scala#L361
Runtime implementation unclear: need to get and carry around an instance mirror of defining value. Has to be done at level of ModuleDef, since pointer to instance is lost after. I'm not sure it's viable to solve for the runtime provisioner
In case we can't solve it we should fail fast at least (better during compilation)
The issue is two-fold
distage-static
works as usual – we get an error "X is an inner class, use instance mirror to instantiate". The only way to capture instance is with a macro, really... We CAN do that, as part of Tag
/TagK
we can detect path-dependent types and include a (weak?) reference to path parent.StaticInnerClassesTest."progression test: compile-time ReflectionProvider can't handle factories inside stable objects that contain inner classes from inherited traits that depend on types defined inside trait"
, or in:trait X {
trait D
case class Class(d: Dep)
trait Factory {
def mkClass(d: Dep): Class
}
}
object x extends X
We get error that in mkClass
parameter d
is not used in the constructor of Class
, even though it's used! This may happen if one of (but not both) is true:
mkClass
the d: Dep
parameter is not instantiated, it's X#Dep
, not x.Dep
Class
, in the constructor signature we get the Dep
is not to our singleton path, so it's X#Dep
, not x.Dep
Either way the d: Dep
in mkClass doesn't match d: Dep
in Class, one of them is not given a correct path.
We can probably solve this easily by keeping track of paths and using .asSeenFrom
in ReflectionProvider
Initially we can just support only top-level object parents. The changes to do this are minimal: Just add logic in ClassStrategy
, TraitStrategy
and FactoryStrategy
to lookup and get parent object via moduleMirror