未验证 提交 0ac0a60e 编写于 作者: 梦境迷离's avatar 梦境迷离 提交者: GitHub

optimize macro (#130)

上级 6caac9de
......@@ -66,8 +66,5 @@ object ProcessorCreator {
* Having two identical type parameters will cause the compiler to recognize error and change the order of generics to avoid.
*/
def apply[Service, RRC, RRP[_ <: Req], RC, Req, Resp]
(
processRequest: (Service, RRC, Req) Resp,
processException: (Service, RC, Exception) Resp
): RRP[Req] = macro ProcessorCreatorMacro.OnlyWithFunctionalParameters[Service, RRC, RRP[_ <: Req], RC, Req, Resp]
(processRequest: (Service, RRC, Req) Resp)(processException: (Service, RC, Exception) Resp): RRP[Req] = macro ProcessorCreatorMacro.OnlyWithFunctionalParameters[Service, RRC, RRP[_ <: Req], RC, Req, Resp]
}
......@@ -41,6 +41,7 @@ object ProcessorCreatorMacro {
processException: c.Expr[(Service, RC, Exception) Req]
)(service: c.Expr[Service], executor: c.Expr[E]): c.Expr[RRP] = { // parameters in order, parameter names differ will compile error
import c.universe._
checkTree[RRC, RRP, RC, Service](c)(needCheckService = false)
val serviceType = weakTypeOf[Service]
val className = TypeName(classNamePrefix + MacroCache.getIdentityId)
val reqProtoType = weakTypeOf[Req]
......@@ -84,7 +85,7 @@ object ProcessorCreatorMacro {
processException: c.Expr[(Service, RC, Exception) Req]
)(service: c.Expr[Service]): c.Expr[RRP] = {
import c.universe._
checkTree[RRC, RRP, RC, Service](c)
checkTree[RRC, RRP, RC, Service](c)(needCheckService = false)
val serviceType = weakTypeOf[Service]
val className = TypeName(classNamePrefix + MacroCache.getIdentityId)
val reqProtoType = weakTypeOf[Req]
......@@ -126,11 +127,12 @@ object ProcessorCreatorMacro {
def OnlyWithFunctionalParameters[Service: c.WeakTypeTag, RRC: c.WeakTypeTag, RRP: c.WeakTypeTag, RC: c.WeakTypeTag, Req: c.WeakTypeTag, Resp: c.WeakTypeTag]
(c: blackbox.Context)(
processRequest: c.Expr[(Service, RRC, Req) Req],
processRequest: c.Expr[(Service, RRC, Req) Req])
(
processException: c.Expr[(Service, RC, Exception) Req]
): c.Expr[RRP] = {
import c.universe._
checkTree[RRC, RRP, RC, Service](c)
checkTree[RRC, RRP, RC, Service](c)(needCheckService = true)
val serviceType = weakTypeOf[Service]
val className = TypeName(classNamePrefix + MacroCache.getIdentityId)
val reqProtoType = weakTypeOf[Req]
......@@ -184,10 +186,11 @@ object ProcessorCreatorMacro {
ret
}
private def checkTree[RRC: c.WeakTypeTag, RRP: c.WeakTypeTag, RC: c.WeakTypeTag, Service: c.WeakTypeTag](c: blackbox.Context): Unit = {
private def checkTree[RRC: c.WeakTypeTag, RRP: c.WeakTypeTag, RC: c.WeakTypeTag, Service: c.WeakTypeTag](c: blackbox.Context)
(needCheckService: Boolean = true): Unit = {
import c.universe._
val serviceType = weakTypeOf[Service]
if (serviceType.typeSymbol.isAbstract || !serviceType.typeSymbol.isClass) {
if (needCheckService && (serviceType.typeSymbol.isAbstract || !serviceType.typeSymbol.isClass)) {
c.abort(c.enclosingPosition, "Not support for abstract classes")
}
if (serviceType.typeSymbol.isModuleClass) {
......
......@@ -99,11 +99,11 @@ class ProcessorCreatorTest extends AnyFlatSpec with Matchers {
val configurationMap = req.getConfigurationMap
val ret = service.openSession(username, password, configurationMap.asScala.toMap)
BOpenSessionResp.newBuilder().setSessionHandle(ret).build()
},
(service, rpc, exception) => {
BOpenSessionResp.newBuilder().setStatus(exception.getLocalizedMessage).build()
}
)
})(
(service, rpc, exception) => {
BOpenSessionResp.newBuilder().setStatus(exception.getLocalizedMessage).build()
}
)
println(openSession.defaultResp)
......@@ -119,7 +119,7 @@ class ProcessorCreatorTest extends AnyFlatSpec with Matchers {
| val openSession = ProcessorCreator[Service, RpcRequestClosure, RpcRequestProcessor, RpcContext, BOpenSessionReq, BOpenSessionResp](
| (service, rpc, req) => {
| BOpenSessionResp.newBuilder().setSessionHandle(null).build()
| },
| })(
| (service, rpc, exception) => {
| BOpenSessionResp.newBuilder().setStatus(exception.getLocalizedMessage).build()
| }
......@@ -140,7 +140,7 @@ class ProcessorCreatorTest extends AnyFlatSpec with Matchers {
| val openSession = ProcessorCreator[Service, RpcRequestProcessor, RpcRequestClosure, RpcContext, BOpenSessionReq, BOpenSessionResp](
| (service, rpc, req) => {
| BOpenSessionResp.newBuilder().setSessionHandle(null).build()
| },
| })(
| (service, rpc, exception) => {
| BOpenSessionResp.newBuilder().setStatus(exception.getLocalizedMessage).build()
| }
......@@ -158,10 +158,10 @@ class ProcessorCreatorTest extends AnyFlatSpec with Matchers {
"ProcessorCreator6" should "compile error" in {
object Service
"""
| val openSession = ProcessorCreator[Service, RpcRequestClosure, RpcRequestProcessor, RpcContext, BOpenSessionReq, BOpenSessionResp](
| val openSession = ProcessorCreator[Service.type, RpcRequestClosure, RpcRequestProcessor, RpcContext, BOpenSessionReq, BOpenSessionResp](
| (service, rpc, req) => {
| BOpenSessionResp.newBuilder().setSessionHandle(null).build()
| },
| })(
| (service, rpc, exception) => {
| BOpenSessionResp.newBuilder().setStatus(exception.getLocalizedMessage).build()
| }
......@@ -174,4 +174,32 @@ class ProcessorCreatorTest extends AnyFlatSpec with Matchers {
| println(openSession.interest())
|""".stripMargin shouldNot compile
}
// not support interface, because it use runtime reflect to create `NetService` instance.
"ProcessorCreator7" should "compile ok" in {
"""
| trait NetService {
| def openSession(username: String, password: String, configuration: Map[String, String] = Map.empty): String
| }
| class NetServiceImpl extends NetService {
| override def openSession(username: String, password: String, configuration: Map[String, String] = Map.empty): String = {
| username + password
| }
| }
| implicit val service: NetService = null
| val openSession = ProcessorCreator[NetService, RpcRequestClosure, RpcRequestProcessor, RpcContext, BOpenSessionReq, BOpenSessionResp](
| (service, _, req) => {
| import scala.jdk.CollectionConverters.MapHasAsScala
| val username = req.getUsername
| val password = req.getPassword
| val configurationMap = req.getConfigurationMap
| val ret = service.openSession(username, password, configurationMap.asScala.toMap)
| BOpenSessionResp.newBuilder().setSessionHandle(ret).build()
| })(
| (_, _, exception) => {
| BOpenSessionResp.newBuilder().setStatus(exception.getLocalizedMessage).build()
| }
| )
|""".stripMargin shouldNot compile
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册