scala.internal.quoted.Expr.scala Maven / Gradle / Ivy
The newest version!
package scala.internal.quoted
import scala.quoted._
import scala.internal.tasty.CompilerInterface.quoteContextWithCompilerInterface
/** An Expr backed by a tree. Only the current compiler trees are allowed.
*
* These expressions are used for arguments of macros. They contain and actual tree
* from the program that is being expanded by the macro.
*
* May contain references to code defined outside this Expr instance.
*/
final class Expr[Tree](val tree: Tree, val scopeId: Int) extends scala.quoted.Expr[Any] {
override def equals(that: Any): Boolean = that match {
case that: Expr[_] =>
// Expr are wrappers around trees, therfore they are equals if their trees are equal.
// All scopeId should be equal unless two different runs of the compiler created the trees.
tree == that.tree && scopeId == that.scopeId
case _ => false
}
def unseal(using qctx: QuoteContext): qctx.reflect.Term =
if (qctx.hashCode != scopeId)
throw new scala.quoted.ScopeException("Cannot call `scala.quoted.staging.run(...)` within a macro or another `run(...)`")
tree.asInstanceOf[qctx.reflect.Term]
override def hashCode: Int = tree.hashCode
override def toString: String = "'{ ... }"
}
object Expr {
/** Pattern matches an the scrutineeExpr against the patternExpr and returns a tuple
* with the matched holes if successful.
*
* Examples:
* - `Matcher.unapply('{ f(0, myInt) })('{ f(0, myInt) }, _)`
* will return `Some(())` (where `()` is a tuple of arity 0)
* - `Matcher.unapply('{ f(0, myInt) })('{ f(patternHole[Int], patternHole[Int]) }, _)`
* will return `Some(Tuple2('{0}, '{ myInt }))`
* - `Matcher.unapply('{ f(0, "abc") })('{ f(0, patternHole[Int]) }, _)`
* will return `None` due to the missmatch of types in the hole
*
* Holes:
* - scala.internal.Quoted.patternHole[T]: hole that matches an expression `x` of type `Expr[U]`
* if `U <:< T` and returns `x` as part of the match.
*
* @param scrutineeExpr `Expr[Any]` on which we are pattern matching
* @param patternExpr `Expr[Any]` containing the pattern tree
* @param hasTypeSplices `Boolean` notify if the pattern has type splices
* @param qctx the current QuoteContext
* @return None if it did not match, `Some(tup)` if it matched where `tup` contains `Expr[Ti]``
*/
def unapply[TypeBindings <: Tuple, Tup <: Tuple](scrutineeExpr: scala.quoted.Expr[Any])
(using patternExpr: scala.quoted.Expr[Any], qctx: QuoteContext): Option[Tup] = {
val qctx1 = quoteContextWithCompilerInterface(qctx)
qctx1.reflect.termMatch(scrutineeExpr.unseal, patternExpr.unseal).asInstanceOf[Option[Tup]]
}
/** Returns a null expresssion equivalent to `'{null}` */
def `null`: QuoteContext ?=> quoted.Expr[Null] = qctx ?=> {
import qctx.reflect._
Literal(Constant.Null()).seal.asInstanceOf[quoted.Expr[Null]]
}
/** Returns a unit expresssion equivalent to `'{}` or `'{()}` */
def Unit: QuoteContext ?=> quoted.Expr[Unit] = qctx ?=> {
import qctx.reflect._
Literal(Constant.Unit()).seal.asInstanceOf[quoted.Expr[Unit]]
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy