0

As part of a macro I need to inspect the patterns of case definitions.

Is there a way to determine the type of a pattern variable, or even the whole pattern?

Consider the polymorphic class Data, and a macro which uses a transformer to inspect and transform patterns over Data values:

case class Data[A](x: String, data: A)

def macroImpl(c: Context)(...) = {

  val transformer = new Transformer {
    override def transformCaseDefs(trees: List[CaseDef]) = trees map {
      case CaseDef(pattern, guard , body) => pattern match {
        case pq"Data($string, $data)" => {
          // What is the type of $data, i.e., how
          // is the type parameter A instantiated?
          ...
        }
      }
    }
  }
  ... 
  transformer.transform(...)
}

Is there a way to determine the type of the pattern variable $data, i.e., a way to determine how the type parameter A has been instantiated?

Another question discusses this problem for trees of values and suggests the use of the c.typeCheck function. Unfortunately, this doesn't seem to work for patterns, since the typeCheck method throws a TypeCheckException when applied to the pattern tree of the example above.

Community
  • 1
  • 1
Martin Zuber
  • 137
  • 6
  • That type won't be known at compile-time (or at least not in the general case). You could e.g. create a (weak) runtime type tag that you could use in the rewritten body, but I'm not sure how useful that would be for what you're trying to do. – Travis Brown Aug 28 '13 at 12:32
  • Would be great if you lodged an issue requesting `typeCheckPattern`. I think it's not too late to put it in 2.11. Also I remember requests for `typeCheckType`, so this might probably be somehow generalizable. – Eugene Burmako Aug 28 '13 at 14:30
  • By the way, what's the tpe of pattern? – Eugene Burmako Aug 28 '13 at 14:31
  • @EugeneBurmako `pattern.tpe` results to `null` in all of my examples. – Martin Zuber Aug 28 '13 at 15:26
  • @EugeneBurmako I created an improvement request for this problem: [SI-7794](https://issues.scala-lang.org/browse/SI-7794) – Martin Zuber Aug 28 '13 at 15:47
  • Thanks for the improvement request. Also, where does pattern come from? Could you show full code? – Eugene Burmako Aug 28 '13 at 17:16
  • @EugeneBurmako As part of my macro I want to perform transformations on all case definitions of a match statement. So the patterns will always stem from a case def in a match. I (slightly) updated the code in the question and attached a full example of such a macro to the improvement request. – Martin Zuber Aug 29 '13 at 11:29
  • Oh, so it's a macro annotation... That might not work even when we fix SI-7794, because c.typeCheck typechecks the argument in the lexical context of the expansion site, not in the context where the tree was originally defined. Would it be possible for your use case to typecheck the entire annottee? – Eugene Burmako Aug 29 '13 at 15:18
  • @EugeneBurmako As part of my application the annotee is a method definition which contains match statements which I want to transform. Thus the type of the annottee would be the type of the method definition, which wouldn't necessarily be useful when inspecting the pattern. Would type checking a pattern be possible if I rewrote the macro annotation into a regular def macro? – Martin Zuber Aug 30 '13 at 10:23
  • If the macro you're using were a def macro, the pattern would've already be typechecked by the type the expansion begins. – Eugene Burmako Aug 30 '13 at 22:08

0 Answers0