Hello folks, I am working on macro that call a method / function. I was able to do an implementation, but I am not happy from way how it is working. My implementation look like :
inline def getSql[T](methodName:String)(using ctx: SqlContext): Sql =
${ getSqlImpl[T]('ctx, 'methodName) }
private def getSqlImpl[T: Type](ctx: Expr[SqlContext], methodNameExpr:Expr[String])(using Quotes): Expr[Sql] = {
....
and invocation looks like :
override def sql: Sql = getSql[TestSelect]("s")
so I must pass the name of the method, in this case āsā and also class (TestSelect
) where method is applied.
I am looking for better solution, I switched from methods to functions, for example:
private[sql] val s = {(name: String, age: Int) => sql"select * ${from[User]} where name = $name and age = $age"}
is function I want to call.
I am struggling with invocation of the function.
Here is almost whole implementation, I skipped only args retrieval:
inline def getSql[T](method: T)(ctx: SqlContext): Sql =
${ getSqlImpl('method, 'ctx) }
private def getSqlImpl[T: Type](m: Expr[T], ctx: Expr[SqlContext])(using Quotes): Expr[Sql] = {
import quotes.reflect.*
val functionClass = TypeRepr.of[T]
// Find the sqlStatement method
val method = functionClass.typeSymbol.methodMember("apply").headOption.getOrElse {
report.errorAndAbort(s"Method apply not found in class ${functionClass.show}")
}
// Get parameter names and types
val paramSymbols = ??? // skipped code
val result = Apply(Select(This(functionClass.typeSymbol), method), args.toList)
result.asExprOf[Sql] // <-- ERROR
}
error is :
[error] | Expected type: com.birl.sql.Sql
[error] | Actual type: Function2.this.R
[error] | Expression: Function2.this.apply(ctx.params.getOrElse[scala.Any]("v
I am not sure what I am doing wrong, but is clear, that function is not invoked.
Thanks for help.