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] = ()
 
}
  
@ExampleAnn
 
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)
3 comments
Comment actions Permalink

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

 
val o: ScObject = null
o
.members.collect {
  case v: ScPatternDefinition =>
    for {
      expr <- v.expr   
      if
expr.isInstanceOf[ScGenericCall]
      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 (v.declaredElements.head.name, argType.get)      
}.flatten


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.

0
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

args.typeArgs.head.getType(TypingContext.empty)
always fails so instead I just use
.getText
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!
0
Comment actions Permalink

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

Best regards,
Alexander Podkhalyuzin.

0

Please sign in to leave a comment.