简短问题:
有没有一种方法可以要求Scala编译器告诉我在程序中的某个点使用的某个隐式是在哪里声明的?
如果没有,是否有算法可以手动跟随以找出隐式声明的位置?
详细问题:
我正在遵循一个简单的spray crud 教程。
在下面的代码片段中(来自此教程的repo):
pathEnd {
post {
entity(as[Question]) { question =>
completeWithLocationHeader(
resourceId = questionService.createQuestion(question),
ifDefinedStatus = 201, ifEmptyStatus = 409)
}
}
} ~
as
接受类型为 FromRequestUnmarshaller[T]
的隐式参数 (完整源代码请参见此处):
def as[T](implicit um: FromRequestUnmarshaller[T]) = um
当我在IntelliJ中使用CMD+SHIFT+P时,询问这个implicit是从哪里来的时,我得到以下回答: 然后,当我遵循第一个提示去查看(链接如下),我会得到以下结果: hint
trait UnmarshallerLifting {
implicit def fromRequestUnmarshaller[T](implicit um: FromMessageUnmarshaller[T]): FromRequestUnmarshaller[T] =
new FromRequestUnmarshaller[T] {
def apply(request: HttpRequest): Deserialized[T] = um(request)
}
...
这并没有帮助我找出隐式的 FromRequestUnmarshaller[T]
是从哪里来的,因为我无法确定 trait UnmarshallerLifting
如何混入到 QuestionResource
中,如果我检查类层次结构:
我检查了看起来可能包含此隐式的 traits,例如这个 trait,但它并不包含该隐式:
trait MarshallingDirectives {
import BasicDirectives._
import MiscDirectives._
import RouteDirectives._
/**
* Unmarshalls the requests entity to the given type passes it to its inner Route.
* If there is a problem with unmarshalling the request is rejected with the [[spray.routing.Rejection]]
* produced by the unmarshaller.
*/
def entity[T](um: FromRequestUnmarshaller[T]): Directive1[T] =
extract(_.request.as(um)).flatMap[T :: HNil] {
case Right(value) ⇒ provide(value)
case Left(ContentExpected) ⇒ reject(RequestEntityExpectedRejection)
case Left(UnsupportedContentType(supported)) ⇒ reject(UnsupportedRequestContentTypeRejection(supported))
case Left(MalformedContent(errorMsg, cause)) ⇒ reject(MalformedRequestContentRejection(errorMsg, cause))
} & cancelAllRejections(ofTypes(RequestEntityExpectedRejection.getClass, classOf[UnsupportedRequestContentTypeRejection]))
/**
* Returns the in-scope FromRequestUnmarshaller for the given type.
*/
def as[T](implicit um: FromRequestUnmarshaller[T]) = um
/**
* Uses the marshaller for the given type to produce a completion function that is passed to its inner route.
* You can use it do decouple marshaller resolution from request completion.
*/
def produce[T](marshaller: ToResponseMarshaller[T]): Directive[(T ⇒ Unit) :: HNil] =
extract { ctx ⇒ (value: T) ⇒ ctx.complete(value)(marshaller) } & cancelAllRejections(ofType[UnacceptedResponseContentTypeRejection])
/**
* Returns the in-scope Marshaller for the given type.
*/
def instanceOf[T](implicit m: ToResponseMarshaller[T]) = m
/**
* Completes the request using the given function. The input to the function is produced with the in-scope
* entity unmarshaller and the result value of the function is marshalled with the in-scope marshaller.
*/
def handleWith[A, B](f: A ⇒ B)(implicit um: FromRequestUnmarshaller[A], m: ToResponseMarshaller[B]): Route =
entity(um) { a ⇒ RouteDirectives.complete(f(a)) }
}
object MarshallingDirectives extends MarshallingDirectives
我已经查看了20个不同的地方,但是感到沮丧。
有没有一种方法可以要求scala编译器告诉我在程序中的某个点(例如这里)使用了一个特定的隐式(在这个例子中是FromRequestUnmarshaller[T]
)是在哪里被声明的?
如果没有这样的方法,是否有一种算法可以手动遵循以找出隐式类型的声明位置?
我在Google和SOF上寻找了这个问题,但是找到的提示都没有帮助。我也阅读了这篇文章,但仍然不知道FromRequestUnmarshaller[T]
来自哪里。