macwire
macwire copied to clipboard
Remove wiring from `def` or add `@NotForWiring`
Currently we have this problem:
case class A()
case class B(a: A)
object Test {
lazy val a: A = wire[A]
def buildSomeA(i: Int): A = A()
lazy val b: B = wire[B] // without `val a`, macwire would produce this: `A(buildSomeA)`...
}
Fails with: Found multiple values of type [A]: [List(buildSomeA, a)]
So 2 things:
- first methods with args are found eligible and they are used without any args (thus producing a compilation error),
- second we quickly end-up with ambiguities
I have the following use case:
class Stuff(clock: Clock)
trait TestBase {
lazy val clock: Clock = Time
def newFrozenClock: Clock
}
class StuffTest extends TestBase {
@Test def doStuff() { wire[Stuff] } // clock is ambiguous
}
So either we ditch def
"support" (I know you've been using it as a "prototype" scope) or we keep it (modulo a little bugfix for parameterized methods) and we introduce another annotation: @NotForWiring
. That way things can be disambiguated once for all:
trait TestBase {
lazy val clock: Clock = Time
@NotForWiring def newFrozenClock: Clock
}
I figured you can workaround the absence of @NotForWiring
by exploiting the lack of support of protected
members (everything that's not public is ineligible):
trait TestBase {
lazy val clock: Clock = Time
protected def newFrozenClock: Clock
}
But that's probably not what your want :) I guess macwire should support protected
members. I'll open an issue.
@NotForWiring
could also be added to types so that:
@NotForWiring
trait MyMatchers {
def matcher1: Matcher[Stuff1] = _
def matcher2: Matcher[Stuff2] = _
}
class MyTest extends MyMatchers {
lazy val stuff: Stuff = wire[Stuff] // MyMatchers isn't analyzed at all, so `matcher1` and `matcher2`
// become ineligible
}
Well using 'def's for wiring is something that I consider a core feature, so I definitely wouldn't remove this. Protected members should work - as anything that is accessible, you are right.
The annotation idea looks good - again as something experimental (I need to mark @Module as such, btw :) ). Again not sure about the name - maybe something with "Ignore"? @IgnoreInWire
?