Scalameta

Scalameta

  • Trees
  • SemanticDB
  • GitHub

›Trees

Trees

  • Guide
  • trees/quasiquotes
  • trees/examples
  • Scastie Playground
  • Scalameta AST Explorer
  • Scaladoc

SemanticDB

  • Guide
  • Specification

Community

  • Built with Scalameta
  • Presentations

trees/quasiquotes

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.

Expressions (meta.Term)

Quasiquote
Literalq"<literal>"
Thisq"this", q"$name.this"
Superq"super", q"$name.super", q"super[$name]", q"$name.super[$name]"
Nameq"<name>" when interpolation is not needed, otherwise Term.Name(name)
Selectionq"$expr.$ename"
InterpolationNot supported yet
Applicationq"$expr(...$exprss)"
Type Applicationq"$expr[..$tpesnel]"
Infix Applicationq"$expr $ename[..$tpes] $expr", q"$expr $ename[..$tpes] (..$exprs)"
Unary Applicationq"!$expr", q"~$expr", q"-$expr", "+$expr"
Assignq"$expr = $expr"
Returnq"return $expr"
Throwq"throw $expr"
Ascribeq"$expr: $tpe"
Annotateq"$expr: ..@$annotsnel"
Tupleq"(..$exprsnel)"
Blockq"{ ..$stats }"
Ifq"if ($expr) $expr else $expr"
Matchq"$expr match { ..case $casesnel }"
Tryq"try $expr catch { ..case $cases } finally $expropt"
Try With Handlerq"try $expr catch $expr finally $expropt"
Functionq"(..$params) => $expr"
Partial Functionq"{ ..case $casesnel }"
Whileq"while ($expr) $expr"
Do Whileq"do $expr while($expr)"
Forq"for (..$enumeratorsnel) $expr"
For Yieldq"for (..$enumeratorsnel) yield $expr"
Newq"new $init"
New Anonymousq"new { ..$stat } with ..$inits { $self => ..$stats }"
Placeholderq"_"
Eta Expansionq"$expr _"
Repeatedq"$expr: _*"

Types (meta.Type)

Quasiquote
Literalt"<literal>"
Namet"<name>" when interpolation is not needed, otherwise Type.Name(name)
Selectiont"$eref.$tname"
Projectiont"$tpe#$tname"
Singletont"$eref.type"
Applicationt"$tpe[..$tpesnel]
Infix Applicationt"$tpe $tname $tpe"
Witht"$tpe with $tpe" (only for supported dialects)
Andt"$tpe & $tpe" (only for supported dialects)
Ort"$tpe | $tpe" (only for supported dialects)
Functiont"(..$tpes) => $tpe"
Implicit Functiont"implicit (..$tpes) => $tpe"
Tuplet"(..$tpesnel)"
Refinet"$tpeopt { ..$stats }"
Existentialt"$tpe forSome { ..$statsnel }"
Annotatet"$tpe ..@$annotsnel"
Lambdat[..$tparams] => $tpe
Methodt(...$paramss): $tpe
Placeholdert"_ >: $tpeopt <: $tpeopt"
By Namet"=> $tpe"
Repeatedt"$tpe*"
VarNot supported

Patterns (meta.Pat) and Cases (meta.Case)

Quasiquote
Literalp"<lit>"
Wildcardp"_"
Sequence Wildcardp"_*"
Varp"<name>"
Bindp"$pat @ $pat"
Alternativep"$pat | $pat"
Tuplep"(..$patsnel)"
Extractp"$expr(..$pats)"
Infix Extractp"$pat $ename (..$pats)"
InterpolationNot supported yet
Typedp"$pat: $tpe"
Namep"`<name>`"
Selectionp"$expr.$ename"
Casep"case $pat if $expropt => $expr"

Members (meta.Member)

Declarations

Quasiquote
Valq"..$mods val ..$patsnel: $tpe"
Varq"..$mods var ..$patsnel: $tpe"
Defq"..$mods def $ename[..$tparams](...$paramss): $tpe"
Typeq"..$mods type $tname[..$tparams] >: $tpeopt <: $tpeopt"

Definitions

Quasiquote
Valq"..$mods val ..$patsnel: $tpeopt = $expr"
Varq"..$mods var ..$patsnel: $tpeopt = $expropt"
Defq"..$mods def $ename[..$tparams](...$paramss): $tpeopt = $expr"
Macroq"..$mods def $ename[..$tparams](...$paramss): $tpeopt = macro $expr"
Typeq"..$mods type $tname[..$tparams] = $tpe"
Classq"..$mods class $tname[..$tparams] ..$ctorMods (...$paramss) $template"
Traitq"..$mods trait $tname[..$tparams] $template"
Objectq"..$mods object $ename $template"
Package Objectq"package object $ename $template"
Packageq"package $eref { ..$stats }"
Primary Ctorq"..$mods def this(...$paramss)"
Secondary Ctorq"..$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.

Value Parameters (meta.Term.Param)

Quasiquote
Term Paramparam"..$mods $name: $tpeopt = $expropt"

Type Parameters (meta.Type.Param)

Quasiquote
Type Paramtparam"..$mods $name[..$tparams] >: $tpeopt <: $tpeopt <% ..$tpes : ..$tpes"

Inits (meta.Init)

Quasiquote
Initinit"$tpe(...$exprss)", init"this(...$exprss)"

Selfs (meta.Self)

Quasiquote
Selfself"$name: $tpeopt", self"this: $tpeopt"

Template (meta.Template)

Quasiquote
Templatetemplate"{ ..$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
Annotationmod"@$annot"
Privatemod"private[$ref]"
Protectedmod"protected[$ref]"
Implicitmod"implicit"
Finalmod"final"
Sealedmod"sealed"
Overridemod"override"
Casemod"case"
Abstractmod"abstract"
Covariantmod"+"
Contravariantmod"-"
Lazymod"lazy"
Val Parammod"valparam"
Var Parammod"varparam"
Inlinemod"inline"

Enumerators (meta.Enum)

Quasiquote
Generatorenumerator"$pat <- $expr"
Valueenumerator"$pat = $expr"
Guardenumerator"if $expr"

Imports (meta.Import)

Quasiquote
Importq"import ..$importersnel"

Importer (meta.Importer)

Quasiquote
Importerimporter"$eref.{..$importeesnel}"

Importees (meta.Importee)

Quasiquote
Nameimportee"$name"
Renameimportee"$name => $name"
Unimportimportee"$name => _"
Wildcardimportee"_"

Sources (meta.Source)

Quasiquote
Sourcesource"..$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:

  1. 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.

  2. 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:

    1. 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".
    2. 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 }.
    3. This list is probably incomplete. Please submit an issue if you find any discrepancies.
  3. An unquote template ($smth, ..$smth or ...$smth) works as follows:

    1. First, we strip standard suffixes from smth using the "Suffixes" table (e.g. exprssnel means a non-empty list of lists of expr).

    2. Second, we figure out the expected type of smth using the "Shorthands" table (e.g. expr means Term, so exprssnel means List[List[Term]]).

    3. 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:

      1. $smth can not be replicated.
      2. ..$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).
      3. ...$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).
      4. If a suffix of smth says that it's a non-empty list, then replication can't result in an empty list.
      5. If a quasiquote is used as a pattern, then some replications may be illegal.
    4. 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.

  4. 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

TypeShorthand
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

SuffixWrapped TypeExample
-sList[_]exprs: List[meta.Term]
-ssList[List[_]]exprss: List[List[meta.Term]]
-optOption[_]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
"""
← Guidetrees/examples →
  • Expressions (meta.Term)
  • Types (meta.Type)
  • Patterns (meta.Pat) and Cases (meta.Case)
  • Members (meta.Member)
    • Declarations
    • Definitions
    • Value Parameters (meta.Term.Param)
    • Type Parameters (meta.Type.Param)
  • Inits (meta.Init)
  • Selfs (meta.Self)
  • Template (meta.Template)
  • Modifiers (meta.Mod)
  • Enumerators (meta.Enum)
  • Imports (meta.Import)
  • Importer (meta.Importer)
  • Importees (meta.Importee)
  • Sources (meta.Source)
  • Legend
    • Shorthands
    • Suffixes
  • Comments
Scalameta
Scalameta Docs
Trees GuideQuasiquotesSemanticDB
Scalameta Projects
Metals: language serverScalafmt: code formatterScalafix: linting and refactoring toolMUnit: testing libraryMDoc: documentation toolMetabrowse: online code browser
Community
GitHub
Copyright © 2025 Scalameta