Below you can find a comprehensive map between Scala's language constructs and
various quasiquotes in scala.meta. If something's missing here, it's a bug that
should be
submitted to our issue tracker.
This specification describes quasiquote syntax using a markedly condensed
notation. If you have troubles decyphering it, consult the "Legend" section in
the end of the document.
q"..$mods class $tname[..$tparams] ..$ctorMods (...$paramss) $template"
Trait
q"..$mods trait $tname[..$tparams] $template"
Object
q"..$mods object $ename $template"
Package Object
q"package object $ename $template"
Package
q"package $eref { ..$stats }"
Primary Ctor
q"..$mods def this(...$paramss)"
Secondary Ctor
q"..$mods def this(...$paramss) = $expr"
$template above can be replaced with either extends followed by the full signature from
Template, or just { $self => ..$stats } if no parents are expected.
template"{ ..$stats } with ..$inits { $self => ..$stats }" (first stats is early initializers, second stats is regular statements in the body of the template).
Modifiers (meta.Mod)
Quasiquote
Annotation
mod"@$annot"
Private
mod"private[$ref]"
Protected
mod"protected[$ref]"
Implicit
mod"implicit"
Final
mod"final"
Sealed
mod"sealed"
Override
mod"override"
Case
mod"case"
Abstract
mod"abstract"
Covariant
mod"+"
Contravariant
mod"-"
Lazy
mod"lazy"
Val Param
mod"valparam"
Var Param
mod"varparam"
Inline
mod"inline"
Enumerators (meta.Enum)
Quasiquote
Generator
enumerator"$pat <- $expr"
Value
enumerator"$pat = $expr"
Guard
enumerator"if $expr"
Imports (meta.Import)
Quasiquote
Import
q"import ..$importersnel"
Importer (meta.Importer)
Quasiquote
Importer
importer"$eref.{..$importeesnel}"
Importees (meta.Importee)
Quasiquote
Name
importee"$name"
Rename
importee"$name => $name"
Unimport
importee"$name => _"
Wildcard
importee"_"
Sources (meta.Source)
Quasiquote
Source
source"..$stats"
Legend
The tables above define quasiquote syntax using a notation called quasiquote
templates. A quasiquote is valid if it conforms to exactly one quasiquote
template according to the following rules:
Any trivia token (e.g. whitespace and comments) in a quasiquote template or a
quasiquote is insignificant and is ignored for the purposes of conformance
testing.
Any non-trivia token in a quasiquote template, except for an unquote
template, means that exactly that token is required in a quasiquote, with the
following exceptions:
Parentheses, brackets and braces around unquotes are oftentimes dropped if
they wrap empty lists, e.g. q"x + y" conforms to
q"$expr $ename[..$tpes] $expr".
with is dropped if there are zero or one inits, e.g. both q"new {}"
and q"new C" conform to
q"new { ..$stat } with ..$inits { $self => ..$stats }.
This list is probably incomplete. Please
submit an issue if
you find any discrepancies.
An unquote template ($smth, ..$smth or ...$smth) works as follows:
First, we strip standard suffixes from smth using the "Suffixes" table
(e.g. exprssnel means a non-empty list of lists of expr).
Second, we figure out the expected type of smth using the "Shorthands"
table (e.g. expr means Term, so exprssnel means List[List[Term]]).
Third, we apply an appropriate number of replications to the unquote
template to have it match the corresponding part of a quasiquote that's
being tested for conformance:
$smth can not be replicated.
..$smth means an arbitrary mix of $smth and ..$smth unquote
templates separated according to their location (e.g. an empty string,
[$tpe], [..$tpes, $tpe] all conform to [..$tpes], and the
separator is a comma, as appropriate for a list of type arguments).
...$smth means an arbitrary mix of $smth, ..$smth and ...$smth
unquote templates, separated according to their location (e.g. an empty
string, (...$exprss), (..$exprs)($expr1, $expr2)() all conform to
(...$exprss), and the separator are matching parentheses, as
appropriate for a list of arguments).
If a suffix of smth says that it's a non-empty list, then replication
can't result in an empty list.
If a quasiquote is used as a pattern, then some replications may be
illegal.
Finally, we match the unquotes after replication against the corresponding
parts of the quasiquote under conformance test. There are three
possibilities for a match: scala syntax, unquote, lifted unquote.
If not specified explicitly, quasiquote templates work for both construction
and deconstruction. In some cases, a template is only applicable to
construction (e.g. it's impossible to pattern match a name without specifying
an expected type explicitly, because patterns like in
term match { case q"$ename" => } will match any term, not limited to just
term names).
Shorthands
Type
Shorthand
meta.Case
$case
meta.Enumerator
$enumerator
meta.Mod
$mod
meta.Mod.Annot
$annot
meta.Name
$name
meta.Importee
$importee
meta.Importer
$importer
meta.Init
$init
meta.Pat
$pat
meta.Ref
$ref
meta.Self
$self
meta.Stat
$stat
meta.Template
$template
meta.Term
$expr
meta.Term.Name
$ename
meta.Term.Ref
$eref
meta.Term.Param
$param
meta.Type
$tpe
meta.Type.Name
$tname
meta.Type.Param
$tparam
Suffixes
Suffix
Wrapped Type
Example
-s
List[_]
exprs: List[meta.Term]
-ss
List[List[_]]
exprss: List[List[meta.Term]]
-opt
Option[_]
expropt: Option[meta.Term]
-nel
_
tpesnel: List[meta.Type]
Comments
Starting with v4.14.3, scalameta supports
comments attached to trees.
Specifically for quasiquotes, the only special case is with interpolated comments
which must be passed as scala strings (since each interpolated value is parsed as
valid scala):
val scaladoc = q"""
"some scaladoc string"
"""
val comment = q"\"some comment string\""
val tree = q"""
/** $scaladoc */
val foo = bar // $comment
"""