Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to distinguish triple quotes from single quotes in macros?

Tags:

macros

scala

I am writing a macro m(expr: String), where expr is an expression in some language (not Scala):

m("SOME EXPRESSION")

m("""
  SOME EXPRESSION
""")

When I am parsing the expression I would like to report error messages with proper locations in the source file. To achieve this I should know the location of the string literal itself and the number of quotes of the literal (3 or 1). Unfortunately, I did not find any method that returns the number of quotes of the literal:

import scala.language.experimental.macros
import scala.reflect.macros.blackbox.Context

object Temp {
  def m(s: String) : String = macro mImpl

  def mImpl(context: Context)(s: context.Expr[String]): context.universe.Tree = {
    import context.universe._

    s match {
      case l @ Literal(Constant(p: String)) =>
        if (l.<TRIPLE QUOTES>) {
          ...
        } else {
          ...
        }

      case _ =>
        context.abort(context.enclosingPosition, "The argument of m must be a string literal")
    }
  }
}

What should I put instead of <TRIPLE QUOTES>?

like image 291
ZhekaKozlov Avatar asked Jul 03 '15 08:07

ZhekaKozlov


1 Answers

The only way i can think of is to access the source file and check for triple quotes:

l.tree.pos.source.content.startsWith("\"\"\"",l.tree.pos.start)

You need also to edit your matching case:

case l @ Expr(Literal(Constant(p: String))) =>

Here the version with some explanation:

val tree: context.universe.Tree = l.tree
val pos: scala.reflect.api.Position = tree.pos
val source: scala.reflect.internal.util.SourceFile = pos.source
val content: Array[Char] = source.content
val start: Int = pos.start
val isTriple: Boolean = content.startsWith("\"\"\"",start)
like image 162
Federico Pellegatta Avatar answered Oct 25 '22 23:10

Federico Pellegatta