macwire icon indicating copy to clipboard operation
macwire copied to clipboard

Remove wiring from `def` or add `@NotForWiring`

Open backuitist opened this issue 9 years ago • 3 comments

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
}

backuitist avatar Sep 17 '15 19:09 backuitist

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.

backuitist avatar Sep 18 '15 11:09 backuitist

@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
}

backuitist avatar Sep 19 '15 13:09 backuitist

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?

adamw avatar Sep 21 '15 09:09 adamw