Scala macro plugin help

Hello, I copied sbt-idea-example to start making a plugin for a macro.

I need help.

If I have a macro annotation that is used like this:

trait Blah2 {
  protected def defAttr[T] = ()
object ExampleObj extends Blah2 {
  val A = defAttr[Int]
  val B = defAttr[String]
  val C = defAttr[Unit]

I know how to get a ScObject for ExampleObj, but how can I inspect the body to get a list of:

  • ("A", Int)
  • ("B", String)
  • ("C", Unit)
Comment actions Permalink

I don't know full requirements, so something like this:

val o: ScObject = null
.members.collect {
  case v: ScPatternDefinition =>
    for {
      expr <- v.expr   
      call = expr.asInstanceOf[ScGenericCall]
      if v.declaredElements.length == 1
      args <- call.typeArgs
      if args.typeArgs.length == 1
argType = args.typeArgs.head.getType(TypingContext.empty)
      if !argType.isEmpty  
      if call.referencedExpr.isInstanceOf[ScReferenceExpression]
      refExpr = call.referencedExpr.asInstanceOf[ScReferenceExpression]
      if refExpr.refName == "defAttr" //here you can check resolve, by refExpr.bind()  
} yield (, argType.get)      

It can be improved by adding for example ScGenericCall extractor, so first three lines will be just ScGenericCall(call) <- v.expr.

Best regards,
Alexander Podkhalyuzin.

Comment actions Permalink

That's extremely helpful. Thank you very much!

I was able to create a plugin that mostly works for my macro.
In my case

always fails so instead I just use
which is enough.

Also I think I've found two issues so I'll raise them on the bug tracker. Thank you again for your help!
Comment actions Permalink

getType should work. So it would be great to fix it as well.

Best regards,
Alexander Podkhalyuzin.


Please sign in to leave a comment.