Skip to content

Commit

Permalink
cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
sijarsu authored and mkrzemien committed Jun 7, 2020
1 parent 7026d2a commit 3935a4c
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 38 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,32 +18,54 @@ private[macwire] class DependencyResolver[C <: blackbox.Context](val c: C, debug
*/
def resolve(param: Symbol, t: Type): Tree = {

eligibleValues.findInFirstScope(t).toList match {
case Nil if isOption(t) =>
getOptionArg(t).flatMap(u => eligibleValues.findInFirstScope(u).toList.headOption) match { //FIXME: handle multiple values (tests, tests...)
case Some(argTree) => q"Some($argTree)"
case None => q"None"
}
case Nil => c.abort(c.enclosingPosition, s"Cannot find a value of type: [$t]")
def resolve(t: Type, handler: (Type, List[Tree]) => Tree): Tree = {
val trees: List[Tree] = eligibleValues.findInFirstScope(t).toList match {
case Nil if isOption(t) => List(resolve(getOptionArg(t).get, optionHandler))
case ts => ts
}
handler(t, trees)
}

def basicHandler(t: Type, trees: List[Tree]): Tree = trees match {
case Nil => noValueError(t)
case value :: Nil =>
val forwardValues = eligibleValues.findInScope(t, LocalForward)
if (forwardValues.nonEmpty) {
c.warning(c.enclosingPosition, s"Found [$value] for parameter [${param.name}], " +
s"but a forward reference [${forwardValues.mkString(", ")}] was also eligible")
}
forwardValuesWarn(value)
value
case values => c.abort(c.enclosingPosition, s"Found multiple values of type [$t]: [$values]")
case values => multipleValuesError(t, values)
}
}

private def isOption(t: Type): Boolean = getOptionArg(t).nonEmpty
def optionHandler(t: Type, trees: List[Tree]): Tree = trees match {
case Nil => q"None"
case value :: Nil if value.equalsStructure(q"None") => q"None"
case value :: Nil =>
forwardValuesWarn(value)
q"Some($value)"
case values => multipleValuesError(t, values)
}

private def getOptionArg(t: Type): Option[Type] = t.baseType(typeOf[Option[_]].typeSymbol) match {
case TypeRef(_, _, arg :: Nil) => Some(arg)
case NoType => None
}
def noValueError(t: Type): Nothing =
c.abort(c.enclosingPosition, s"Cannot find a value of type: [$t]")

def multipleValuesError(t: Type, values: List[Tree]): Nothing =
c.abort(c.enclosingPosition, s"Found multiple values of type [$t]: [$values]")


def forwardValuesWarn(value: Tree): Unit = {
val forwardValues = eligibleValues.findInScope(t, LocalForward)
if (forwardValues.nonEmpty) {
c.warning(c.enclosingPosition, s"Found [$value] for parameter [${param.name}], " +
s"but a forward reference [${forwardValues.mkString(", ")}] was also eligible")
}
}

def isOption(t: Type): Boolean = getOptionArg(t).nonEmpty

def getOptionArg(t: Type): Option[Type] = t.baseType(typeOf[Option[_]].typeSymbol) match {
case TypeRef(_, _, arg :: Nil) => Some(arg)
case NoType => None
}

resolve(t, basicHandler)
}

/** @return all the instances of type `t` that are accessible.
*/
Expand Down
20 changes: 20 additions & 0 deletions tests/src/test/resources/test-cases/_t142_nested.success
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
class A()
class B(val oa: Option[Option[A]])

object TestSome {
val a = Some(new A())
val b = wire[B]
}

object TestNestedSome {
val a = new A()
val b = wire[B]
}

object TestNone {
val b = wire[B]
}

require(TestSome.b.oa.contains(TestSome.a))
require(TestNestedSome.b.oa.get.contains(TestNestedSome.a))
require(TestNone.b.oa.isEmpty)
18 changes: 0 additions & 18 deletions tests/src/test/scala/com/softwaremill/macwire/WireTest.scala

This file was deleted.

0 comments on commit 3935a4c

Please sign in to comment.