scala.quoted.runtime.impl.QuotesImpl.scala Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of scala3-compiler_3 Show documentation
Show all versions of scala3-compiler_3 Show documentation
scala3-compiler-bootstrapped
package scala.quoted
package runtime.impl
import scala.language.unsafeNulls
import dotty.tools.dotc
import dotty.tools.dotc.ast.tpd
import dotty.tools.dotc.ast.untpd
import dotty.tools.dotc.core.Annotations
import dotty.tools.dotc.core.Contexts.*
import dotty.tools.dotc.core.Decorators.*
import dotty.tools.dotc.core.NameKinds
import dotty.tools.dotc.core.NameOps.*
import dotty.tools.dotc.core.StdNames.*
import dotty.tools.dotc.core.Types
import dotty.tools.dotc.NoCompilationUnit
import dotty.tools.dotc.quoted.MacroExpansion
import dotty.tools.dotc.quoted.PickledQuotes
import dotty.tools.dotc.quoted.reflect.*
import scala.quoted.runtime.{QuoteUnpickler, QuoteMatching}
import scala.quoted.runtime.impl.printers.*
import scala.reflect.TypeTest
import dotty.tools.dotc.core.NameKinds.ExceptionBinderName
object QuotesImpl {
def apply()(using Context): Quotes =
new QuotesImpl
def showDecompiledTree(tree: tpd.Tree)(using Context): String =
import qctx.reflect.Printer.{TreeCode, TreeAnsiCode}
val qctx: QuotesImpl = new QuotesImpl(using MacroExpansion.context(tree))
if ctx.settings.color.value == "always" then TreeAnsiCode.show(tree)
else TreeCode.show(tree)
}
class QuotesImpl private (using val ctx: Context) extends Quotes, QuoteUnpickler, QuoteMatching:
private val xCheckMacro: Boolean = ctx.settings.XcheckMacros.value
private val yDebugMacro: Boolean = ctx.settings.YdebugMacros.value
extension [T](self: scala.quoted.Expr[T])
def show: String =
reflect.Printer.TreeCode.show(reflect.asTerm(self))
def matches(that: scala.quoted.Expr[Any]): Boolean =
QuoteMatcher(yDebugMacro).treeMatch(reflect.asTerm(self), reflect.asTerm(that)).nonEmpty
def valueOrAbort(using fromExpr: FromExpr[T]): T =
def reportError =
val tree = reflect.asTerm(self)
val code = reflect.Printer.TreeCode.show(tree)
val msg = s"Expected a known value. \n\nThe value of: $code\ncould not be extracted using $fromExpr"
reflect.report.throwError(msg, self)
fromExpr.unapply(self)(using QuotesImpl.this).getOrElse(reportError)
end extension
extension (self: scala.quoted.Expr[Any])
/** Checks is the `quoted.Expr[?]` is valid expression of type `X` */
def isExprOf[X](using scala.quoted.Type[X]): Boolean =
reflect.TypeReprMethods.<:<(reflect.asTerm(self).tpe)(reflect.TypeRepr.of[X])
/** Convert this to an `quoted.Expr[X]` if this expression is a valid expression of type `X` or throws */
def asExprOf[X](using scala.quoted.Type[X]): scala.quoted.Expr[X] = {
if self.isExprOf[X] then
self.asInstanceOf[scala.quoted.Expr[X]]
else
throw ExprCastException(
expectedType = reflect.Printer.TypeReprCode.show(reflect.TypeRepr.of[X]),
actualType = reflect.Printer.TypeReprCode.show(reflect.asTerm(self).tpe),
exprCode = self.show
)
}
end extension
object reflect extends reflectModule:
object CompilationInfo extends CompilationInfoModule:
def isWhileTyping: Boolean = !ctx.isAfterTyper
def XmacroSettings: List[String] = ctx.settings.XmacroSettings.value
end CompilationInfo
extension (expr: Expr[Any])
def asTerm: Term = expr.asInstanceOf[ExprImpl].tree
end extension
type Tree = tpd.Tree
object Tree extends TreeModule
given TreeMethods: TreeMethods with
extension (self: Tree)
def pos: Position =
val treePos = self.sourcePos
if treePos.exists then treePos
else
if xCheckMacro then report.warning(s"Missing tree position (defaulting to position 0): ${Printer.TreeStructure.show(self)}\nThis is a compiler bug. Please report it.")
self.source.atSpan(dotc.util.Spans.Span(0))
def symbol: Symbol = self.symbol
def show(using printer: Printer[Tree]): String = printer.show(self)
def isExpr: Boolean =
self match
case TermTypeTest(self) =>
self.tpe.widen match
case _: MethodType | _: PolyType => false
case _ => true
case _ => false
def asExpr: scala.quoted.Expr[Any] =
if self.isExpr then
new ExprImpl(self, SpliceScope.getCurrent)
else self match
case TermTypeTest(self) => throw new Exception("Expected an expression. This is a partially applied Term. Try eta-expanding the term first.")
case _ => throw new Exception("Expected a Term but was: " + Printer.TreeStructure.show(self))
end extension
extension (self: Tree)
def asExprOf[T](using tp: scala.quoted.Type[T]): scala.quoted.Expr[T] =
QuotesImpl.this.asExprOf(self.asExpr)[T](using tp)
end extension
extension [ThisTree <: Tree](self: ThisTree)
def changeOwner(newOwner: Symbol): ThisTree =
tpd.TreeOps(self).changeNonLocalOwners(newOwner).asInstanceOf[ThisTree]
end extension
end TreeMethods
type PackageClause = tpd.PackageDef
object PackageClauseTypeTest extends TypeTest[Tree, PackageClause]:
def unapply(x: Tree): Option[PackageClause & x.type] = x match
case x: (tpd.PackageDef & x.type) => Some(x)
case _ => None
end PackageClauseTypeTest
object PackageClause extends PackageClauseModule:
def apply(pid: Ref, stats: List[Tree]): PackageClause =
withDefaultPos(tpd.PackageDef(pid.asInstanceOf[tpd.RefTree], stats))
def copy(original: Tree)(pid: Ref, stats: List[Tree]): PackageClause =
tpd.cpy.PackageDef(original)(pid, stats)
def unapply(tree: PackageClause): (Ref, List[Tree]) =
(tree.pid, tree.stats)
end PackageClause
given PackageClauseMethods: PackageClauseMethods with
extension (self: PackageClause)
def pid: Ref = self.pid
def stats: List[Tree] = self.stats
end extension
end PackageClauseMethods
type Import = tpd.Import
object ImportTypeTest extends TypeTest[Tree, Import]:
def unapply(x: Tree): Option[Import & x.type] = x match
case tree: (tpd.Import & x.type) => Some(tree)
case _ => None
end ImportTypeTest
object Import extends ImportModule:
def apply(expr: Term, selectors: List[Selector]): Import =
if selectors.isEmpty then throw IllegalArgumentException("Empty selectors")
withDefaultPos(tpd.Import(expr, selectors))
def copy(original: Tree)(expr: Term, selectors: List[Selector]): Import =
if selectors.isEmpty then throw IllegalArgumentException("Empty selectors")
tpd.cpy.Import(original)(expr, selectors)
def unapply(tree: Import): (Term, List[Selector]) =
(tree.expr, tree.selectors)
end Import
given ImportMethods: ImportMethods with
extension (self: Import)
def expr: Term = self.expr
def selectors: List[Selector] = self.selectors
end extension
end ImportMethods
type Export = tpd.Export
object ExportTypeTest extends TypeTest[Tree, Export]:
def unapply(x: Tree): Option[Export & x.type] = x match
case tree: (tpd.Export & x.type) => Some(tree)
case _ => None
end ExportTypeTest
object Export extends ExportModule:
def unapply(tree: Export): (Term, List[Selector]) =
(tree.expr, tree.selectors)
end Export
given ExportMethods: ExportMethods with
extension (self: Export)
def expr: Term = self.expr
def selectors: List[Selector] = self.selectors
end extension
end ExportMethods
type Statement = tpd.Tree
object StatementTypeTest extends TypeTest[Tree, Statement]:
def unapply(x: Tree): Option[Statement & x.type] = x match
case TermTypeTest(x: x.type) => Some(x)
case DefinitionTypeTest(x: x.type) => Some(x)
case ImportTypeTest(x: x.type) => Some(x)
case ExportTypeTest(x: x.type) => Some(x)
case _ => None
end StatementTypeTest
type Definition = tpd.MemberDef
object DefinitionTypeTest extends TypeTest[Tree, Definition]:
def unapply(x: Tree): Option[Definition & x.type] = x match
case x: (tpd.MemberDef & x.type) => Some(x)
case _ => None
end DefinitionTypeTest
object Definition extends DefinitionModule
given DefinitionMethods: DefinitionMethods with
extension (self: Definition)
def name: String = self match
case self: tpd.MemberDef => self.name.toString
end extension
end DefinitionMethods
type ClassDef = tpd.TypeDef
object ClassDefTypeTest extends TypeTest[Tree, ClassDef]:
def unapply(x: Tree): Option[ClassDef & x.type] = x match
case x: (tpd.TypeDef & x.type) if x.isClassDef => Some(x)
case _ => None
end ClassDefTypeTest
object ClassDef extends ClassDefModule:
def apply(cls: Symbol, parents: List[Tree], body: List[Statement]): ClassDef =
val untpdCtr = untpd.DefDef(nme.CONSTRUCTOR, Nil, tpd.TypeTree(dotc.core.Symbols.defn.UnitClass.typeRef), tpd.EmptyTree)
val ctr = ctx.typeAssigner.assignType(untpdCtr, cls.primaryConstructor)
tpd.ClassDefWithParents(cls.asClass, ctr, parents, body)
def copy(original: Tree)(name: String, constr: DefDef, parents: List[Tree], selfOpt: Option[ValDef], body: List[Statement]): ClassDef = {
val dotc.ast.Trees.TypeDef(_, originalImpl: tpd.Template) = original: @unchecked
tpd.cpy.TypeDef(original)(name.toTypeName, tpd.cpy.Template(originalImpl)(constr, parents, derived = Nil, selfOpt.getOrElse(tpd.EmptyValDef), body))
}
def unapply(cdef: ClassDef): (String, DefDef, List[Tree /* Term | TypeTree */], Option[ValDef], List[Statement]) =
val rhs = cdef.rhs.asInstanceOf[tpd.Template]
(cdef.name.toString, cdef.constructor, cdef.parents, cdef.self, rhs.body)
def module(module: Symbol, parents: List[Tree /* Term | TypeTree */], body: List[Statement]): (ValDef, ClassDef) = {
val cls = module.moduleClass
val clsDef = ClassDef(cls, parents, body)
val newCls = Apply(Select(New(TypeIdent(cls)), cls.primaryConstructor), Nil)
val modVal = ValDef(module, Some(newCls))
(modVal, clsDef)
}
end ClassDef
given ClassDefMethods: ClassDefMethods with
extension (self: ClassDef)
def constructor: DefDef =
self.rhs.asInstanceOf[tpd.Template].constr
def parents: List[Tree] =
self.rhs.asInstanceOf[tpd.Template].parents
def self: Option[ValDef] =
optional(self.rhs.asInstanceOf[tpd.Template].self)
def body: List[Statement] =
self.rhs.asInstanceOf[tpd.Template].body
end extension
end ClassDefMethods
type DefDef = tpd.DefDef
object DefDefTypeTest extends TypeTest[Tree, DefDef]:
def unapply(x: Tree): Option[DefDef & x.type] = x match
case x: (tpd.DefDef & x.type) => Some(x)
case _ => None
end DefDefTypeTest
object DefDef extends DefDefModule:
def apply(symbol: Symbol, rhsFn: List[List[Tree]] => Option[Term]): DefDef =
xCheckMacroAssert(symbol.isTerm, s"expected a term symbol but received $symbol")
xCheckMacroAssert(symbol.flags.is(Flags.Method), "expected a symbol with `Method` flag set")
withDefaultPos(tpd.DefDef(symbol.asTerm, prefss =>
xCheckedMacroOwners(xCheckMacroValidExpr(rhsFn(prefss)), symbol).getOrElse(tpd.EmptyTree)
))
def copy(original: Tree)(name: String, paramss: List[ParamClause], tpt: TypeTree, rhs: Option[Term]): DefDef =
tpd.cpy.DefDef(original)(name.toTermName, paramss, tpt, xCheckedMacroOwners(rhs, original.symbol).getOrElse(tpd.EmptyTree))
def unapply(ddef: DefDef): (String, List[ParamClause], TypeTree, Option[Term]) =
(ddef.name.toString, ddef.paramss, ddef.tpt, optional(ddef.rhs))
end DefDef
given DefDefMethods: DefDefMethods with
extension (self: DefDef)
def paramss: List[ParamClause] = self.paramss
def leadingTypeParams: List[TypeDef] = self.leadingTypeParams
def trailingParamss: List[ParamClause] = self.trailingParamss
def termParamss: List[TermParamClause] = self.termParamss
def returnTpt: TypeTree = self.tpt
def rhs: Option[Term] = optional(self.rhs)
end extension
end DefDefMethods
type ValDef = tpd.ValDef
object ValDefTypeTest extends TypeTest[Tree, ValDef]:
def unapply(x: Tree): Option[ValDef & x.type] = x match
case x: (tpd.ValDef & x.type) => Some(x)
case _ => None
end ValDefTypeTest
object ValDef extends ValDefModule:
def apply(symbol: Symbol, rhs: Option[Term]): ValDef =
xCheckMacroAssert(!symbol.flags.is(Flags.Method), "expected a symbol without `Method` flag set")
withDefaultPos(tpd.ValDef(symbol.asTerm, xCheckedMacroOwners(xCheckMacroValidExpr(rhs), symbol).getOrElse(tpd.EmptyTree)))
def copy(original: Tree)(name: String, tpt: TypeTree, rhs: Option[Term]): ValDef =
tpd.cpy.ValDef(original)(name.toTermName, tpt, xCheckedMacroOwners(xCheckMacroValidExpr(rhs), original.symbol).getOrElse(tpd.EmptyTree))
def unapply(vdef: ValDef): (String, TypeTree, Option[Term]) =
(vdef.name.toString, vdef.tpt, optional(vdef.rhs))
def let(owner: Symbol, name: String, rhs: Term)(body: Ref => Term): Term =
val vdef = tpd.SyntheticValDef(name.toTermName, rhs)(using ctx.withOwner(owner))
val ref = tpd.ref(vdef.symbol).asInstanceOf[Ref]
Block(List(vdef), body(ref))
def let(owner: Symbol, terms: List[Term])(body: List[Ref] => Term): Term =
val ctx1 = ctx.withOwner(owner)
val vdefs = terms.map(term => tpd.SyntheticValDef("x".toTermName, term)(using ctx1))
val refs = vdefs.map(vdef => tpd.ref(vdef.symbol).asInstanceOf[Ref])
Block(vdefs, body(refs))
end ValDef
given ValDefMethods: ValDefMethods with
extension (self: ValDef)
def tpt: TypeTree = self.tpt
def rhs: Option[Term] = optional(self.rhs)
end extension
end ValDefMethods
type TypeDef = tpd.TypeDef
object TypeDefTypeTest extends TypeTest[Tree, TypeDef]:
def unapply(x: Tree): Option[TypeDef & x.type] = x match
case x: (tpd.TypeDef & x.type) if !x.isClassDef => Some(x)
case _ => None
end TypeDefTypeTest
object TypeDef extends TypeDefModule:
def apply(symbol: Symbol): TypeDef =
withDefaultPos(tpd.TypeDef(symbol.asType))
def copy(original: Tree)(name: String, rhs: Tree): TypeDef =
tpd.cpy.TypeDef(original)(name.toTypeName, rhs)
def unapply(tdef: TypeDef): (String, Tree /*TypeTree | TypeBoundsTree*/ /* TypeTree | TypeBoundsTree */) =
(tdef.name.toString, tdef.rhs)
end TypeDef
given TypeDefMethods: TypeDefMethods with
extension (self: TypeDef)
def rhs: Tree = self.rhs
end extension
end TypeDefMethods
type Term = tpd.Tree
object TermTypeTest extends TypeTest[Tree, Term]:
def unapply(x: Tree): Option[Term & x.type] = x match
case x: tpd.PatternTree => None
case x: (tpd.SeqLiteral & x.type) => Some(x)
case x: (tpd.Inlined & x.type) => Some(x)
case x: (tpd.NamedArg & x.type) => Some(x)
case x: (tpd.Typed & x.type) =>
TypedTypeTest.unapply(x) // Matches `Typed` but not `TypedOrTest`
case _ => if x.isTerm then Some(x) else None
end TermTypeTest
object Term extends TermModule:
def betaReduce(tree: Term): Option[Term] =
val tree1 = new dotty.tools.dotc.ast.tpd.TreeMap {
override def transform(tree: Tree)(using Context): Tree = tree match {
case tpd.Block(Nil, _) | tpd.Inlined(_, Nil, _) =>
super.transform(tree)
case tpd.Apply(sel @ tpd.Select(expr, nme), args) =>
val tree1 = cpy.Apply(tree)(cpy.Select(sel)(transform(expr), nme), args)
dotc.transform.BetaReduce(tree1).withSpan(tree.span)
case tpd.Apply(ta @ tpd.TypeApply(sel @ tpd.Select(expr: Apply, nme), tpts), args) =>
val tree1 = cpy.Apply(tree)(cpy.TypeApply(ta)(cpy.Select(sel)(transform(expr), nme), tpts), args)
dotc.transform.BetaReduce(tree1).withSpan(tree.span)
case _ =>
dotc.transform.BetaReduce(tree).withSpan(tree.span)
}
}.transform(tree)
if tree1 == tree then None else Some(tree1)
end Term
given TermMethods: TermMethods with
extension (self: Term)
def seal: scala.quoted.Expr[Any] =
if self.isExpr then new ExprImpl(self, SpliceScope.getCurrent)
else throw new Exception("Cannot seal a partially applied Term. Try eta-expanding the term first.")
def sealOpt: Option[scala.quoted.Expr[Any]] =
if self.isExpr then Some(new ExprImpl(self, SpliceScope.getCurrent))
else None
def tpe: TypeRepr = self.tpe.widenSkolem
def underlyingArgument: Term = new tpd.TreeOps(self).underlyingArgument
def underlying: Term = new tpd.TreeOps(self).underlying
def etaExpand(owner: Symbol): Term = self.tpe.widen match {
case mtpe: Types.MethodType if !mtpe.isParamDependent =>
val closureResType = mtpe.resType match {
case t: Types.MethodType => t.toFunctionType(isJava = self.symbol.is(dotc.core.Flags.JavaDefined))
case t => t
}
val closureTpe = Types.MethodType(mtpe.paramNames, mtpe.paramInfos, closureResType)
val closureMethod = dotc.core.Symbols.newAnonFun(owner, closureTpe)
tpd.Closure(closureMethod, tss => new tpd.TreeOps(self).appliedToTermArgs(tss.head).etaExpand(closureMethod))
case _ => self
}
def appliedTo(arg: Term): Term =
self.appliedToArgs(arg :: Nil)
def appliedTo(arg: Term, args: Term*): Term =
self.appliedToArgs(arg :: args.toList)
def appliedToArgs(args: List[Term]): Apply =
Apply(self, args)
def appliedToArgss(argss: List[List[Term]]): Term =
argss.foldLeft(self: Term)(Apply(_, _))
def appliedToNone: Apply =
self.appliedToArgs(Nil)
def appliedToType(targ: TypeRepr): Term =
self.appliedToTypes(targ :: Nil)
def appliedToTypes(targs: List[TypeRepr]): Term =
self.appliedToTypeTrees(targs map (Inferred(_)))
def appliedToTypeTrees(targs: List[TypeTree]): Term =
if (targs.isEmpty) self else TypeApply(self, targs)
def select(sym: Symbol): Select = Select(self, sym)
end extension
end TermMethods
type Ref = tpd.RefTree
object RefTypeTest extends TypeTest[Tree, Ref]:
def unapply(x: Tree): Option[Ref & x.type] = x match
case x: (tpd.RefTree & x.type) if x.isTerm => Some(x)
case _ => None
end RefTypeTest
object Ref extends RefModule:
def term(tp: TermRef): Ref =
withDefaultPos(tpd.ref(tp).asInstanceOf[tpd.RefTree])
def apply(sym: Symbol): Ref =
assert(sym.isTerm)
val refTree = tpd.ref(sym) match
case t @ tpd.This(ident) => // not a RefTree, so we need to work around this - issue #19732
// ident in `This` can be a TypeIdent of sym, so we manually prepare the ref here,
// knowing that the owner is actually `This`.
val term = Select(This(sym.owner), sym)
term.asInstanceOf[tpd.RefTree]
case other => other.asInstanceOf[tpd.RefTree]
withDefaultPos(refTree)
end Ref
type Ident = tpd.Ident
object IdentTypeTest extends TypeTest[Tree, Ident]:
def unapply(x: Tree): Option[Ident & x.type] = x match
case x: (tpd.Ident & x.type) if x.isTerm => Some(x)
case _ => None
end IdentTypeTest
object Ident extends IdentModule:
def apply(tmref: TermRef): Term =
withDefaultPos(tpd.ref(tmref).asInstanceOf[Term])
def copy(original: Tree)(name: String): Ident =
tpd.cpy.Ident(original)(name.toTermName)
def unapply(tree: Ident): Some[String] =
Some(tree.name.toString)
end Ident
given IdentMethods: IdentMethods with
extension (self: Ident)
def name: String = self.name.toString
end extension
end IdentMethods
type Wildcard = tpd.Ident
object WildcardTypeTest extends TypeTest[Tree, Wildcard]:
def unapply(x: Tree): Option[Wildcard & x.type] = x match
case x: (tpd.Ident & x.type) if x.name == nme.WILDCARD => Some(x)
case _ => None
end WildcardTypeTest
object Wildcard extends WildcardModule:
def apply(): Wildcard =
withDefaultPos(untpd.Ident(nme.WILDCARD).withType(dotc.core.Symbols.defn.AnyType))
def unapply(pattern: Wildcard): true = true
end Wildcard
type Select = tpd.Select
object SelectTypeTest extends TypeTest[Tree, Select]:
def unapply(x: Tree): Option[Select & x.type] = x match
case x: (tpd.Select & x.type) if x.isTerm => Some(x)
case _ => None
end SelectTypeTest
object Select extends SelectModule:
def apply(qualifier: Term, symbol: Symbol): Select =
withDefaultPos(tpd.Select(qualifier, Types.TermRef(qualifier.tpe, symbol)))
def unique(qualifier: Term, name: String): Select =
val denot = qualifier.tpe.member(name.toTermName)
assert(!denot.isOverloaded, s"The symbol `$name` is overloaded. The method Select.unique can only be used for non-overloaded symbols.")
withDefaultPos(tpd.Select(qualifier, name.toTermName))
def overloaded(qualifier: Term, name: String, targs: List[TypeRepr], args: List[Term]): Term =
withDefaultPos(tpd.applyOverloaded(qualifier, name.toTermName, args, targs, Types.WildcardType))
def overloaded(qualifier: Term, name: String, targs: List[TypeRepr], args: List[Term], returnType: TypeRepr): Term =
withDefaultPos(tpd.applyOverloaded(qualifier, name.toTermName, args, targs, returnType))
def copy(original: Tree)(qualifier: Term, name: String): Select =
tpd.cpy.Select(original)(qualifier, name.toTermName)
def unapply(x: Select): (Term, String) =
(x.qualifier, x.name.toString)
end Select
given SelectMethods: SelectMethods with
extension (self: Select)
def qualifier: Term = self.qualifier
def name: String = self.name.toString
def signature: Option[Signature] =
if self.symbol.signature == dotc.core.Signature.NotAMethod then None
else Some(self.symbol.signature)
end extension
end SelectMethods
type Literal = tpd.Literal
object LiteralTypeTest extends TypeTest[Tree, Literal]:
def unapply(x: Tree): Option[Literal & x.type] = x match
case x: (tpd.Literal & x.type) => Some(x)
case _ => None
end LiteralTypeTest
object Literal extends LiteralModule:
def apply(constant: Constant): Literal =
withDefaultPos(tpd.Literal(constant))
def copy(original: Tree)(constant: Constant): Literal =
tpd.cpy.Literal(original)(constant)
def unapply(x: Literal): Some[Constant] =
Some(x.constant)
end Literal
given LiteralMethods: LiteralMethods with
extension (self: Literal)
def constant: Constant = self.const
end extension
end LiteralMethods
type This = tpd.This
object ThisTypeTest extends TypeTest[Tree, This]:
def unapply(x: Tree): Option[This & x.type] = x match
case x: (tpd.This & x.type) => Some(x)
case _ => None
end ThisTypeTest
object This extends ThisModule:
def apply(cls: Symbol): This =
withDefaultPos(tpd.This(cls.asClass))
def copy(original: Tree)(qual: Option[String]): This =
tpd.cpy.This(original)(qual.map(x => untpd.Ident(x.toTypeName)).getOrElse(untpd.EmptyTypeIdent))
def unapply(x: This): Some[Option[String]] =
Some(optional(x.qual).map(_.name.toString))
end This
given ThisMethods: ThisMethods with
extension (self: This)
def id: Option[String] = optional(self.qual).map(_.name.toString)
end extension
end ThisMethods
type New = tpd.New
object NewTypeTest extends TypeTest[Tree, New]:
def unapply(x: Tree): Option[New & x.type] = x match
case x: (tpd.New & x.type) => Some(x)
case _ => None
end NewTypeTest
object New extends NewModule:
def apply(tpt: TypeTree): New =
withDefaultPos(tpd.New(tpt))
def copy(original: Tree)(tpt: TypeTree): New =
tpd.cpy.New(original)(tpt)
def unapply(x: New): Some[TypeTree] = Some(x.tpt)
end New
given NewMethods: NewMethods with
extension (self: New)
def tpt: TypeTree = self.tpt
end extension
end NewMethods
type NamedArg = tpd.NamedArg
object NamedArgTypeTest extends TypeTest[Tree, NamedArg]:
def unapply(x: Tree): Option[NamedArg & x.type] = x match
case x: (tpd.NamedArg & x.type) if x.name.isInstanceOf[dotc.core.Names.TermName] => Some(x) // TODO: Now, the name should alwas be a term name
case _ => None
end NamedArgTypeTest
object NamedArg extends NamedArgModule:
def apply(name: String, arg: Term): NamedArg =
withDefaultPos(tpd.NamedArg(name.toTermName, xCheckMacroValidExpr(arg)))
def copy(original: Tree)(name: String, arg: Term): NamedArg =
tpd.cpy.NamedArg(original)(name.toTermName, xCheckMacroValidExpr(arg))
def unapply(x: NamedArg): (String, Term) =
(x.name.toString, x.value)
end NamedArg
given NamedArgMethods: NamedArgMethods with
extension (self: NamedArg)
def name: String = self.name.toString
def value: Term = self.arg
end extension
end NamedArgMethods
type Apply = tpd.Apply | tpd.Quote | tpd.Splice
object ApplyTypeTest extends TypeTest[Tree, Apply]:
def unapply(x: Tree): Option[Apply & x.type] = x match
case x: (tpd.Apply & x.type) => Some(x)
case x: (tpd.Quote & x.type) => Some(x) // TODO expose Quote AST in Quotes
case x: (tpd.Splice & x.type) => Some(x) // TODO expose Splice AST in Quotes
case _ => None
end ApplyTypeTest
object Apply extends ApplyModule:
def apply(fun: Term, args: List[Term]): Apply =
xCheckMacroAssert(fun.tpe.widen.isInstanceOf[dotc.core.Types.MethodType], "Expected `fun.tpe` to widen into a `MethodType`")
xCheckMacroValidExprs(args)
withDefaultPos(tpd.Apply(fun, args))
def copy(original: Tree)(fun: Term, args: List[Term]): Apply =
xCheckMacroAssert(fun.tpe.widen.isInstanceOf[dotc.core.Types.MethodType], "Expected `fun.tpe` to widen into a `MethodType`")
xCheckMacroValidExprs(args)
tpd.cpy.Apply(original)(fun, args)
def unapply(x: Apply): (Term, List[Term]) =
(x.fun, x.args)
end Apply
given ApplyMethods: ApplyMethods with
extension (self: Apply)
def fun: Term = self match
case self: tpd.Apply => self.fun
case self: tpd.Quote => // TODO expose Quote AST in Quotes
import dotty.tools.dotc.ast.tpd.TreeOps
tpd.ref(dotc.core.Symbols.defn.QuotedRuntime_exprQuote)
.appliedToType(self.bodyType)
.withSpan(self.span)
case self: tpd.Splice => // TODO expose Splice AST in Quotes
import dotty.tools.dotc.ast.tpd.TreeOps
tpd.ref(dotc.core.Symbols.defn.QuotedRuntime_exprSplice)
.appliedToType(self.tpe)
.withSpan(self.span)
def args: List[Term] = self match
case self: tpd.Apply => self.args
case self: tpd.Quote => List(self.body) // TODO expose Quote AST in Quotes
case self: tpd.Splice => List(self.expr) // TODO expose Splice AST in Quotes
end extension
end ApplyMethods
type TypeApply = tpd.TypeApply
object TypeApplyTypeTest extends TypeTest[Tree, TypeApply]:
def unapply(x: Tree): Option[TypeApply & x.type] = x match
case x: (tpd.TypeApply & x.type) => Some(x)
case _ => None
end TypeApplyTypeTest
object TypeApply extends TypeApplyModule:
def apply(fun: Term, args: List[TypeTree]): TypeApply =
xCheckMacroAssert(fun.tpe.widen.isInstanceOf[dotc.core.Types.PolyType], "Expected `fun.tpe` to widen into a `PolyType`")
withDefaultPos(tpd.TypeApply(fun, args))
def copy(original: Tree)(fun: Term, args: List[TypeTree]): TypeApply =
xCheckMacroAssert(fun.tpe.widen.isInstanceOf[dotc.core.Types.PolyType], "Expected `fun.tpe` to widen into a `PolyType`")
tpd.cpy.TypeApply(original)(fun, args)
def unapply(x: TypeApply): (Term, List[TypeTree]) =
(x.fun, x.args)
end TypeApply
given TypeApplyMethods: TypeApplyMethods with
extension (self: TypeApply)
def fun: Term = self.fun
def args: List[TypeTree] = self.args
end extension
end TypeApplyMethods
type Super = tpd.Super
object SuperTypeTest extends TypeTest[Tree, Super]:
def unapply(x: Tree): Option[Super & x.type] = x match
case x: (tpd.Super & x.type) => Some(x)
case _ => None
end SuperTypeTest
object Super extends SuperModule:
def apply(qual: Term, mix: Option[String]): Super =
withDefaultPos(tpd.Super(qual, mix.map(x => untpd.Ident(x.toTypeName)).getOrElse(untpd.EmptyTypeIdent), dotc.core.Symbols.NoSymbol))
def copy(original: Tree)(qual: Term, mix: Option[String]): Super =
tpd.cpy.Super(original)(qual, mix.map(x => untpd.Ident(x.toTypeName)).getOrElse(untpd.EmptyTypeIdent))
def unapply(x: Super): (Term, Option[String]) =
(x.qualifier, x.id)
end Super
given SuperMethods: SuperMethods with
extension (self: Super)
def qualifier: Term = self.qual
def id: Option[String] = optional(self.mix).map(_.name.toString)
def idPos: Position = self.mix.sourcePos
end extension
end SuperMethods
type Typed = tpd.Typed
object TypedTypeTest extends TypeTest[Tree, Typed]:
def unapply(x: Tree): Option[Typed & x.type] = x match
case x: (tpd.Typed & x.type) =>
x.expr match
case TermTypeTest(_) => Some(x)
case _ => None
case _ => None
end TypedTypeTest
object Typed extends TypedModule:
def apply(expr: Term, tpt: TypeTree): Typed =
withDefaultPos(tpd.Typed(xCheckMacroValidExpr(expr), tpt))
def copy(original: Tree)(expr: Term, tpt: TypeTree): Typed =
tpd.cpy.Typed(original)(xCheckMacroValidExpr(expr), tpt)
def unapply(x: Typed): (Term, TypeTree) =
(x.expr, x.tpt)
end Typed
given TypedMethods: TypedMethods with
extension (self: Typed)
def expr: Term = self.expr
def tpt: TypeTree = self.tpt
end extension
end TypedMethods
type TypedOrTest = tpd.Typed
object TypedOrTestTypeTest extends TypeTest[Tree, TypedOrTest]:
def unapply(x: Tree): Option[TypedOrTest & x.type] = x match
case x: (tpd.Typed & x.type) => Some(x)
case _ => None
end TypedOrTestTypeTest
object TypedOrTest extends TypedOrTestModule:
def apply(expr: Term, tpt: TypeTree): Typed =
withDefaultPos(tpd.Typed(xCheckMacroValidExpr(expr), tpt))
def copy(original: Tree)(expr: Term, tpt: TypeTree): Typed =
tpd.cpy.Typed(original)(xCheckMacroValidExpr(expr), tpt)
def unapply(x: Typed): (Term, TypeTree) =
(x.expr, x.tpt)
end TypedOrTest
given TypedOrTestMethods: TypedOrTestMethods with
extension (self: Typed)
def tree: Tree = self.expr
def tpt: TypeTree = self.tpt
end extension
end TypedOrTestMethods
type Assign = tpd.Assign
object AssignTypeTest extends TypeTest[Tree, Assign]:
def unapply(x: Tree): Option[Assign & x.type] = x match
case x: (tpd.Assign & x.type) => Some(x)
case _ => None
end AssignTypeTest
object Assign extends AssignModule:
def apply(lhs: Term, rhs: Term): Assign =
withDefaultPos(tpd.Assign(lhs, xCheckMacroValidExpr(rhs)))
def copy(original: Tree)(lhs: Term, rhs: Term): Assign =
tpd.cpy.Assign(original)(lhs, xCheckMacroValidExpr(rhs))
def unapply(x: Assign): (Term, Term) =
(x.lhs, x.rhs)
end Assign
given AssignMethods: AssignMethods with
extension (self: Assign)
def lhs: Term = self.lhs
def rhs: Term = self.rhs
end extension
end AssignMethods
type Block = tpd.Block
object BlockTypeTest extends TypeTest[Tree, Block]:
def unapply(x: Tree): Option[Block & x.type] = x match
case x: (tpd.Block & x.type) => Some(x)
case _ => None
end BlockTypeTest
object Block extends BlockModule:
def apply(stats: List[Statement], expr: Term): Block =
xCheckMacroBlockOwners(withDefaultPos(tpd.Block(stats, xCheckMacroValidExpr(expr))))
def copy(original: Tree)(stats: List[Statement], expr: Term): Block =
xCheckMacroBlockOwners(tpd.cpy.Block(original)(stats, expr))
def unapply(x: Block): (List[Statement], Term) =
(x.statements, x.expr)
end Block
given BlockMethods: BlockMethods with
extension (self: Block)
def statements: List[Statement] = self.stats
def expr: Term = self.expr
end extension
end BlockMethods
type Closure = tpd.Closure
object ClosureTypeTest extends TypeTest[Tree, Closure]:
def unapply(x: Tree): Option[Closure & x.type] = x match
case x: (tpd.Closure & x.type) => Some(x)
case _ => None
end ClosureTypeTest
object Closure extends ClosureModule:
def apply(meth: Term, tpe: Option[TypeRepr]): Closure =
withDefaultPos(tpd.Closure(Nil, meth, tpe.map(tpd.TypeTree(_)).getOrElse(tpd.EmptyTree)))
def copy(original: Tree)(meth: Tree, tpe: Option[TypeRepr]): Closure =
tpd.cpy.Closure(original)(Nil, meth, tpe.map(tpd.TypeTree(_)).getOrElse(tpd.EmptyTree))
def unapply(x: Closure): (Term, Option[TypeRepr]) =
(x.meth, x.tpeOpt)
end Closure
given ClosureMethods: ClosureMethods with
extension (self: Closure)
def meth: Term = self.meth
def tpeOpt: Option[TypeRepr] = optional(self.tpt).map(_.tpe)
end extension
end ClosureMethods
object Lambda extends LambdaModule:
def apply(owner: Symbol, tpe: MethodType, rhsFn: (Symbol, List[Tree]) => Tree): Block =
val meth = dotc.core.Symbols.newAnonFun(owner, tpe)
withDefaultPos(tpd.Closure(meth, tss => xCheckedMacroOwners(xCheckMacroValidExpr(rhsFn(meth, tss.head.map(withDefaultPos))), meth)))
def unapply(tree: Block): Option[(List[ValDef], Term)] = tree match {
case Block((ddef @ DefDef(_, tpd.ValDefs(params) :: Nil, _, Some(body))) :: Nil, Closure(meth, _))
if ddef.symbol == meth.symbol =>
Some((params, body))
case _ => None
}
end Lambda
type If = tpd.If
object IfTypeTest extends TypeTest[Tree, If]:
def unapply(x: Tree): Option[If & x.type] = x match
case x: (tpd.If & x.type) => Some(x)
case _ => None
end IfTypeTest
object If extends IfModule:
def apply(cond: Term, thenp: Term, elsep: Term): If =
withDefaultPos(tpd.If(xCheckMacroValidExpr(cond), xCheckMacroValidExpr(thenp), xCheckMacroValidExpr(elsep)))
def copy(original: Tree)(cond: Term, thenp: Term, elsep: Term): If =
tpd.cpy.If(original)(xCheckMacroValidExpr(cond), xCheckMacroValidExpr(thenp), xCheckMacroValidExpr(elsep))
def unapply(tree: If): (Term, Term, Term) =
(tree.cond, tree.thenp, tree.elsep)
end If
given IfMethods: IfMethods with
extension (self: If)
def cond: Term = self.cond
def thenp: Term = self.thenp
def elsep: Term = self.elsep
def isInline: Boolean = self.isInline
end extension
end IfMethods
type Match = tpd.Match
object MatchTypeTest extends TypeTest[Tree, Match]:
def unapply(x: Tree): Option[Match & x.type] = x match
case x: (tpd.Match & x.type) if !x.selector.isEmpty => Some(x)
case _ => None
end MatchTypeTest
object Match extends MatchModule:
def apply(selector: Term, cases: List[CaseDef]): Match =
withDefaultPos(tpd.Match(xCheckMacroValidExpr(selector), cases))
def copy(original: Tree)(selector: Term, cases: List[CaseDef]): Match =
tpd.cpy.Match(original)(xCheckMacroValidExpr(selector), cases)
def unapply(x: Match): (Term, List[CaseDef]) =
(x.scrutinee, x.cases)
end Match
given MatchMethods: MatchMethods with
extension (self: Match)
def scrutinee: Term = self.selector
def cases: List[CaseDef] = self.cases
def isInline: Boolean = self.isInline
end extension
end MatchMethods
type SummonFrom = tpd.Match
object SummonFromTypeTest extends TypeTest[Tree, SummonFrom]:
def unapply(x: Tree): Option[SummonFrom & x.type] = x match
case x: (tpd.Match & x.type) if x.selector.isEmpty => Some(x)
case _ => None
end SummonFromTypeTest
object SummonFrom extends SummonFromModule:
def apply(cases: List[CaseDef]): SummonFrom =
withDefaultPos(tpd.Match(tpd.EmptyTree, cases))
def copy(original: Tree)(cases: List[CaseDef]): SummonFrom =
tpd.cpy.Match(original)(tpd.EmptyTree, cases)
def unapply(x: SummonFrom): Some[List[CaseDef]] =
Some(x.cases)
end SummonFrom
given SummonFromMethods: SummonFromMethods with
extension (self: SummonFrom)
def cases: List[CaseDef] = self.cases
end extension
end SummonFromMethods
type Try = tpd.Try
object TryTypeTest extends TypeTest[Tree, Try]:
def unapply(x: Tree): Option[Try & x.type] = x match
case x: (tpd.Try & x.type) => Some(x)
case _ => None
end TryTypeTest
object Try extends TryModule:
def apply(expr: Term, cases: List[CaseDef], finalizer: Option[Term]): Try =
withDefaultPos(tpd.Try(xCheckMacroValidExpr(expr), cases, finalizer.getOrElse(tpd.EmptyTree)))
def copy(original: Tree)(expr: Term, cases: List[CaseDef], finalizer: Option[Term]): Try =
tpd.cpy.Try(original)(xCheckMacroValidExpr(expr), cases, finalizer.getOrElse(tpd.EmptyTree))
def unapply(x: Try): (Term, List[CaseDef], Option[Term]) =
(x.body, x.cases, optional(x.finalizer))
end Try
given TryMethods: TryMethods with
extension (self: Try)
def body: Term = self.expr
def cases: List[CaseDef] = self.cases
def finalizer: Option[Term] = optional(self.finalizer)
end extension
end TryMethods
type Return = tpd.Return
object ReturnTypeTest extends TypeTest[Tree, Return]:
def unapply(x: Tree): Option[Return & x.type] = x match
case x: (tpd.Return & x.type) => Some(x)
case _ => None
end ReturnTypeTest
object Return extends ReturnModule:
def apply(expr: Term, from: Symbol): Return =
withDefaultPos(tpd.Return(xCheckMacroValidExpr(expr), from))
def copy(original: Tree)(expr: Term, from: Symbol): Return =
tpd.cpy.Return(original)(xCheckMacroValidExpr(expr), tpd.ref(from))
def unapply(x: Return): (Term, Symbol) =
(x.expr, x.from.symbol)
end Return
given ReturnMethods: ReturnMethods with
extension (self: Return)
def expr: Term = self.expr
def from: Symbol = self.from.symbol
end extension
end ReturnMethods
type Repeated = tpd.SeqLiteral
object RepeatedTypeTest extends TypeTest[Tree, Repeated]:
def unapply(x: Tree): Option[Repeated & x.type] = x match
case x: (tpd.SeqLiteral & x.type) => Some(x)
case _ => None
end RepeatedTypeTest
object Repeated extends RepeatedModule:
def apply(elems: List[Term], elemtpt: TypeTree): Repeated =
xCheckMacroValidExprs(elems)
withDefaultPos(tpd.SeqLiteral(elems, elemtpt))
def copy(original: Tree)(elems: List[Term], elemtpt: TypeTree): Repeated =
xCheckMacroValidExprs(elems)
tpd.cpy.SeqLiteral(original)(elems, elemtpt)
def unapply(x: Repeated): (List[Term], TypeTree) =
(x.elems, x.elemtpt)
end Repeated
given RepeatedMethods: RepeatedMethods with
extension (self: Repeated)
def elems: List[Term] = self.elems
def elemtpt: TypeTree = self.elemtpt
end extension
end RepeatedMethods
type Inlined = tpd.Inlined
object InlinedTypeTest extends TypeTest[Tree, Inlined]:
def unapply(x: Tree): Option[Inlined & x.type] = x match
case x: (tpd.Inlined & x.type) => Some(x)
case _ => None
end InlinedTypeTest
object Inlined extends InlinedModule:
def apply(call: Option[Tree], bindings: List[Definition], expansion: Term): Inlined =
withDefaultPos(tpd.Inlined(call.getOrElse(tpd.EmptyTree), bindings.map { case b: tpd.MemberDef => b }, xCheckMacroValidExpr(expansion)))
def copy(original: Tree)(call: Option[Tree], bindings: List[Definition], expansion: Term): Inlined =
tpd.cpy.Inlined(original)(call.getOrElse(tpd.EmptyTree), bindings.asInstanceOf[List[tpd.MemberDef]], xCheckMacroValidExpr(expansion))
def unapply(x: Inlined): (Option[Tree /* Term | TypeTree */], List[Definition], Term) =
(optional(x.call), x.bindings, x.body)
end Inlined
given InlinedMethods: InlinedMethods with
extension (self: Inlined)
def call: Option[Tree] = optional(self.call)
def bindings: List[Definition] = self.bindings
def body: Term = self.expansion
end extension
end InlinedMethods
type SelectOuter = tpd.Select
object SelectOuterTypeTest extends TypeTest[Tree, SelectOuter]:
def unapply(x: Tree): Option[SelectOuter & x.type] = x match
case x: (tpd.Select & x.type) =>
x.name match
case NameKinds.OuterSelectName(_, _) => Some(x)
case _ => None
case _ => None
end SelectOuterTypeTest
object SelectOuter extends SelectOuterModule:
def apply(qualifier: Term, name: String, levels: Int): SelectOuter =
withDefaultPos(tpd.Select(qualifier, NameKinds.OuterSelectName(name.toTermName, levels)))
def copy(original: Tree)(qualifier: Term, name: String, levels: Int): SelectOuter =
tpd.cpy.Select(original)(qualifier, NameKinds.OuterSelectName(name.toTermName, levels))
def unapply(x: SelectOuter): (Term, String, Int) =
(x.qualifier, x.name.toString, x.level)
end SelectOuter
given SelectOuterMethods: SelectOuterMethods with
extension (self: SelectOuter)
def qualifier: Term = self.qualifier
def name: String = self.name.toString
def level: Int =
val NameKinds.OuterSelectName(_, levels) = self.name: @unchecked
levels
end extension
end SelectOuterMethods
type While = tpd.WhileDo
object WhileTypeTest extends TypeTest[Tree, While]:
def unapply(x: Tree): Option[While & x.type] = x match
case x: (tpd.WhileDo & x.type) => Some(x)
case _ => None
end WhileTypeTest
object While extends WhileModule:
def apply(cond: Term, body: Term): While =
withDefaultPos(tpd.WhileDo(xCheckMacroValidExpr(cond), xCheckMacroValidExpr(body)))
def copy(original: Tree)(cond: Term, body: Term): While =
tpd.cpy.WhileDo(original)(xCheckMacroValidExpr(cond), xCheckMacroValidExpr(body))
def unapply(x: While): (Term, Term) =
(x.cond, x.body)
end While
given WhileMethods: WhileMethods with
extension (self: While)
def cond: Term = self.cond
def body: Term = self.body
end extension
end WhileMethods
type TypeTree = tpd.Tree
object TypeTreeTypeTest extends TypeTest[Tree, TypeTree]:
def unapply(x: Tree): Option[TypeTree & x.type] = x match
case TypeBoundsTreeTypeTest(_) => None
case x: (tpd.Tree & x.type) if x.isType => Some(x)
case _ => None
end TypeTreeTypeTest
object TypeTree extends TypeTreeModule:
def of[T <: AnyKind](using tp: scala.quoted.Type[T]): TypeTree =
tp.asInstanceOf[TypeImpl].typeTree
def ref(sym: Symbol): TypeTree =
assert(sym.isType, "Expected a type symbol, but got " + sym)
tpd.ref(sym)
end TypeTree
given TypeTreeMethods: TypeTreeMethods with
extension (self: TypeTree)
def tpe: TypeRepr = self.tpe.stripTypeVar
end extension
end TypeTreeMethods
type Inferred = tpd.TypeTree
object InferredTypeTest extends TypeTest[Tree, Inferred]:
def unapply(x: Tree): Option[Inferred & x.type] = x match
case tpt: (tpd.TypeTree & x.type) if !tpt.tpe.isInstanceOf[Types.TypeBounds] => Some(tpt)
case _ => None
end InferredTypeTest
object Inferred extends InferredModule:
def apply(tpe: TypeRepr): Inferred =
withDefaultPos(tpd.TypeTree(tpe))
def unapply(x: Inferred): true = true
end Inferred
type TypeIdent = tpd.Ident
object TypeIdentTypeTest extends TypeTest[Tree, TypeIdent]:
def unapply(x: Tree): Option[TypeIdent & x.type] = x match
case tpt: (tpd.Ident & x.type) if tpt.isType && tpt.name != nme.WILDCARD => Some(tpt)
case _ => None
end TypeIdentTypeTest
object TypeIdent extends TypeIdentModule:
def apply(sym: Symbol): TypeTree =
assert(sym.isType)
withDefaultPos(tpd.ref(sym).asInstanceOf[tpd.TypeTree])
def copy(original: Tree)(name: String): TypeIdent =
tpd.cpy.Ident(original)(name.toTypeName)
def unapply(x: TypeIdent): Some[String] =
Some(x.name.toString)
end TypeIdent
given TypeIdentMethods: TypeIdentMethods with
extension (self: TypeIdent)
def name: String = self.name.toString
end extension
end TypeIdentMethods
type TypeSelect = tpd.Select
object TypeSelectTypeTest extends TypeTest[Tree, TypeSelect]:
def unapply(x: Tree): Option[TypeSelect & x.type] = x match
case tpt: (tpd.Select & x.type) if tpt.isType && tpt.qualifier.isTerm => Some(tpt)
case _ => None
end TypeSelectTypeTest
object TypeSelect extends TypeSelectModule:
def apply(qualifier: Term, name: String): TypeSelect =
withDefaultPos(tpd.Select(qualifier, name.toTypeName))
def copy(original: Tree)(qualifier: Term, name: String): TypeSelect =
tpd.cpy.Select(original)(qualifier, name.toTypeName)
def unapply(x: TypeSelect): (Term, String) =
(x.qualifier, x.name.toString)
end TypeSelect
given TypeSelectMethods: TypeSelectMethods with
extension (self: TypeSelect)
def qualifier: Term = self.qualifier
def name: String = self.name.toString
end extension
end TypeSelectMethods
type TypeProjection = tpd.Select
object TypeProjectionTypeTest extends TypeTest[Tree, TypeProjection]:
def unapply(x: Tree): Option[TypeProjection & x.type] = x match
case tpt: (tpd.Select & x.type) if tpt.isType && tpt.qualifier.isType => Some(tpt)
case _ => None
end TypeProjectionTypeTest
object TypeProjection extends TypeProjectionModule:
def copy(original: Tree)(qualifier: TypeTree, name: String): TypeProjection =
tpd.cpy.Select(original)(qualifier, name.toTypeName)
def unapply(x: TypeProjection): (TypeTree, String) =
(x.qualifier, x.name.toString)
end TypeProjection
given TypeProjectionMethods: TypeProjectionMethods with
extension (self: TypeProjection)
def qualifier: TypeTree = self.qualifier
def name: String = self.name.toString
end extension
end TypeProjectionMethods
type Singleton = tpd.SingletonTypeTree
object SingletonTypeTest extends TypeTest[Tree, Singleton]:
def unapply(x: Tree): Option[Singleton & x.type] = x match
case tpt: (tpd.SingletonTypeTree & x.type) => Some(tpt)
case _ => None
end SingletonTypeTest
object Singleton extends SingletonModule:
def apply(ref: Term): Singleton =
withDefaultPos(tpd.SingletonTypeTree(ref))
def copy(original: Tree)(ref: Term): Singleton =
tpd.cpy.SingletonTypeTree(original)(ref)
def unapply(x: Singleton): Some[Term] =
Some(x.ref)
end Singleton
given SingletonMethods: SingletonMethods with
extension (self: Singleton)
def ref: Term = self.ref
end extension
end SingletonMethods
type Refined = tpd.RefinedTypeTree
object RefinedTypeTest extends TypeTest[Tree, Refined]:
def unapply(x: Tree): Option[Refined & x.type] = x match
case tpt: (tpd.RefinedTypeTree & x.type) => Some(tpt)
case _ => None
end RefinedTypeTest
object Refined extends RefinedModule:
def copy(original: Tree)(tpt: TypeTree, refinements: List[Definition]): Refined =
tpd.cpy.RefinedTypeTree(original)(tpt, refinements)
def unapply(x: Refined): (TypeTree, List[Definition]) =
(x.tpt, x.refinements.asInstanceOf[List[Definition]])
end Refined
given RefinedMethods: RefinedMethods with
extension (self: Refined)
def tpt: TypeTree = self.tpt
def refinements: List[Definition] = self.refinements.asInstanceOf[List[Definition]]
end extension
end RefinedMethods
type Applied = tpd.AppliedTypeTree
object AppliedTypeTest extends TypeTest[Tree, Applied]:
def unapply(x: Tree): Option[Applied & x.type] = x match
case tpt: (tpd.AppliedTypeTree & x.type) => Some(tpt)
case _ => None
end AppliedTypeTest
object Applied extends AppliedModule:
def apply(tpt: TypeTree, args: List[Tree]): Applied =
withDefaultPos(tpd.AppliedTypeTree(tpt, args))
def copy(original: Tree)(tpt: TypeTree, args: List[Tree]): Applied =
tpd.cpy.AppliedTypeTree(original)(tpt, args)
def unapply(x: Applied): (TypeTree, List[Tree /*TypeTree | TypeBoundsTree*/]) =
(x.tpt, x.args)
end Applied
given AppliedMethods: AppliedMethods with
extension (self: Applied)
def tpt: TypeTree = self.tpt
def args: List[Tree] = self.args
end extension
end AppliedMethods
type Annotated = tpd.Annotated
object AnnotatedTypeTest extends TypeTest[Tree, Annotated]:
def unapply(x: Tree): Option[Annotated & x.type] = x match
case tpt: (tpd.Annotated & x.type) => Some(tpt)
case _ => None
end AnnotatedTypeTest
object Annotated extends AnnotatedModule:
def apply(arg: TypeTree, annotation: Term): Annotated =
withDefaultPos(tpd.Annotated(arg, annotation))
def copy(original: Tree)(arg: TypeTree, annotation: Term): Annotated =
tpd.cpy.Annotated(original)(arg, annotation)
def unapply(x: Annotated): (TypeTree, Term) =
(x.arg, x.annotation)
end Annotated
given AnnotatedMethods: AnnotatedMethods with
extension (self: Annotated)
def arg: TypeTree = self.arg
def annotation: Term = self.annot
end extension
end AnnotatedMethods
type MatchTypeTree = tpd.MatchTypeTree
object MatchTypeTreeTypeTest extends TypeTest[Tree, MatchTypeTree]:
def unapply(x: Tree): Option[MatchTypeTree & x.type] = x match
case tpt: (tpd.MatchTypeTree & x.type) => Some(tpt)
case _ => None
end MatchTypeTreeTypeTest
object MatchTypeTree extends MatchTypeTreeModule:
def apply(bound: Option[TypeTree], selector: TypeTree, cases: List[TypeCaseDef]): MatchTypeTree =
withDefaultPos(tpd.MatchTypeTree(bound.getOrElse(tpd.EmptyTree), selector, cases))
def copy(original: Tree)(bound: Option[TypeTree], selector: TypeTree, cases: List[TypeCaseDef]): MatchTypeTree =
tpd.cpy.MatchTypeTree(original)(bound.getOrElse(tpd.EmptyTree), selector, cases)
def unapply(x: MatchTypeTree): (Option[TypeTree], TypeTree, List[TypeCaseDef]) =
(optional(x.bound), x.selector, x.cases)
end MatchTypeTree
given MatchTypeTreeMethods: MatchTypeTreeMethods with
extension (self: MatchTypeTree)
def bound: Option[TypeTree] = optional(self.bound)
def selector: TypeTree = self.selector
def cases: List[TypeCaseDef] = self.cases
end extension
end MatchTypeTreeMethods
type ByName = tpd.ByNameTypeTree
object ByNameTypeTest extends TypeTest[Tree, ByName]:
def unapply(x: Tree): Option[ByName & x.type] = x match
case tpt: (tpd.ByNameTypeTree & x.type) => Some(tpt)
case _ => None
end ByNameTypeTest
object ByName extends ByNameModule:
def apply(result: TypeTree): ByName =
withDefaultPos(tpd.ByNameTypeTree(result))
def copy(original: Tree)(result: TypeTree): ByName =
tpd.cpy.ByNameTypeTree(original)(result)
def unapply(x: ByName): Some[TypeTree] =
Some(x.result)
end ByName
given ByNameMethods: ByNameMethods with
extension (self: ByName)
def result: TypeTree = self.result
end extension
end ByNameMethods
type LambdaTypeTree = tpd.LambdaTypeTree
object LambdaTypeTreeTypeTest extends TypeTest[Tree, LambdaTypeTree]:
def unapply(x: Tree): Option[LambdaTypeTree & x.type] = x match
case tpt: (tpd.LambdaTypeTree & x.type) => Some(tpt)
case _ => None
end LambdaTypeTreeTypeTest
object LambdaTypeTree extends LambdaTypeTreeModule:
def apply(tparams: List[TypeDef], body: Tree): LambdaTypeTree =
withDefaultPos(tpd.LambdaTypeTree(tparams, body))
def copy(original: Tree)(tparams: List[TypeDef], body: Tree): LambdaTypeTree =
tpd.cpy.LambdaTypeTree(original)(tparams, body)
def unapply(tree: LambdaTypeTree): (List[TypeDef], Tree /*TypeTree | TypeBoundsTree*/) =
(tree.tparams, tree.body)
end LambdaTypeTree
given LambdaTypeTreeMethods: LambdaTypeTreeMethods with
extension (self: LambdaTypeTree)
def tparams: List[TypeDef] = self.tparams
def body: Tree = self.body
end extension
end LambdaTypeTreeMethods
type TypeBind = tpd.Bind
object TypeBindTypeTest extends TypeTest[Tree, TypeBind]:
def unapply(x: Tree): Option[TypeBind & x.type] = x match
case tpt: (tpd.Bind & x.type) if tpt.name.isTypeName => Some(tpt)
case _ => None
end TypeBindTypeTest
object TypeBind extends TypeBindModule:
def copy(original: Tree)(name: String, tpt: Tree): TypeBind =
tpd.cpy.Bind(original)(name.toTypeName, tpt)
def unapply(x: TypeBind): (String, Tree /*TypeTree | TypeBoundsTree*/) =
(x.name.toString, x.body)
end TypeBind
given TypeBindMethods: TypeBindMethods with
extension (self: TypeBind)
def name: String = self.name.toString
def body: Tree = self.body
end extension
end TypeBindMethods
type TypeBlock = tpd.Block
object TypeBlockTypeTest extends TypeTest[Tree, TypeBlock]:
def unapply(x: Tree): Option[TypeBlock & x.type] = x match
case tpt: (tpd.Block & x.type) => Some(tpt)
case _ => None
end TypeBlockTypeTest
object TypeBlock extends TypeBlockModule:
def apply(aliases: List[TypeDef], tpt: TypeTree): TypeBlock =
withDefaultPos(tpd.Block(aliases, tpt))
def copy(original: Tree)(aliases: List[TypeDef], tpt: TypeTree): TypeBlock =
tpd.cpy.Block(original)(aliases, tpt)
def unapply(x: TypeBlock): (List[TypeDef], TypeTree) =
(x.aliases, x.tpt)
end TypeBlock
given TypeBlockMethods: TypeBlockMethods with
extension (self: TypeBlock)
def aliases: List[TypeDef] = self.stats.map { case alias: TypeDef => alias }
def tpt: TypeTree = self.expr
end extension
end TypeBlockMethods
type TypeBoundsTree = tpd.TypeBoundsTree | tpd.TypeTree
object TypeBoundsTreeTypeTest extends TypeTest[Tree, TypeBoundsTree]:
def unapply(x: Tree): Option[TypeBoundsTree & x.type] = x match
case x: (tpd.TypeBoundsTree & x.type) => Some(x)
case x: (tpd.TypeTree & x.type) =>
x.tpe match
case tpe: Types.TypeBounds => Some(x)
case _ => None
case _ => None
end TypeBoundsTreeTypeTest
object TypeBoundsTree extends TypeBoundsTreeModule:
def apply(low: TypeTree, hi: TypeTree): TypeBoundsTree =
withDefaultPos(tpd.TypeBoundsTree(low, hi))
def copy(original: Tree)(low: TypeTree, hi: TypeTree): TypeBoundsTree =
tpd.cpy.TypeBoundsTree(original)(low, hi, tpd.EmptyTree)
def unapply(x: TypeBoundsTree): (TypeTree, TypeTree) =
(x.low, x.hi)
end TypeBoundsTree
given TypeBoundsTreeMethods: TypeBoundsTreeMethods with
extension (self: TypeBoundsTree)
def tpe: TypeBounds = self.tpe.asInstanceOf[Types.TypeBounds]
def low: TypeTree = self match
case self: tpd.TypeBoundsTree => self.lo
case self: tpd.TypeTree => makeTypeDef(self.tpe.asInstanceOf[Types.TypeBounds].lo)
def hi: TypeTree = self match
case self: tpd.TypeBoundsTree => self.hi
case self: tpd.TypeTree => makeTypeDef(self.tpe.asInstanceOf[Types.TypeBounds].hi)
private def makeTypeDef(tpe: Types.Type) =
tpd.TypeTree(tpe)(using ctx.withSource(self.source)).withSpan(self.span)
end extension
end TypeBoundsTreeMethods
type WildcardTypeTree = tpd.Ident
object WildcardTypeTreeTypeTest extends TypeTest[Tree, WildcardTypeTree]:
def unapply(x: Tree): Option[WildcardTypeTree & x.type] = x match
case x: (tpd.Ident & x.type) if x.isType && x.name == nme.WILDCARD => Some(x)
case _ => None
end WildcardTypeTreeTypeTest
object WildcardTypeTree extends WildcardTypeTreeModule:
def apply(tpe: TypeRepr): WildcardTypeTree = withDefaultPos(tpd.Underscore(tpe))
def unapply(x: WildcardTypeTree): true = true
end WildcardTypeTree
given WildcardTypeTreeMethods: WildcardTypeTreeMethods with
extension (self: WildcardTypeTree)
def tpe: TypeRepr = self.tpe.stripTypeVar
end extension
end WildcardTypeTreeMethods
type CaseDef = tpd.CaseDef
object CaseDefTypeTest extends TypeTest[Tree, CaseDef]:
def unapply(x: Tree): Option[CaseDef & x.type] = x match
case tree: (tpd.CaseDef & x.type) if tree.body.isTerm => Some(tree)
case _ => None
end CaseDefTypeTest
object CaseDef extends CaseDefModule:
def apply(pattern: Tree, guard: Option[Term], rhs: Term): CaseDef =
tpd.CaseDef(pattern, guard.getOrElse(tpd.EmptyTree), rhs)
def copy(original: Tree)(pattern: Tree, guard: Option[Term], rhs: Term): CaseDef =
tpd.cpy.CaseDef(original)(pattern, guard.getOrElse(tpd.EmptyTree), rhs)
def unapply(x: CaseDef): (Tree, Option[Term], Term) =
(x.pat, optional(x.guard), x.body)
end CaseDef
given CaseDefMethods: CaseDefMethods with
extension (self: CaseDef)
def pattern: Tree = self.pat
def guard: Option[Term] = optional(self.guard)
def rhs: Term = self.body
end extension
end CaseDefMethods
type TypeCaseDef = tpd.CaseDef
object TypeCaseDefTypeTest extends TypeTest[Tree, TypeCaseDef]:
def unapply(x: Tree): Option[TypeCaseDef & x.type] = x match
case tree: (tpd.CaseDef & x.type) if tree.body.isType => Some(tree)
case _ => None
end TypeCaseDefTypeTest
object TypeCaseDef extends TypeCaseDefModule:
def apply(pattern: TypeTree, rhs: TypeTree): TypeCaseDef =
tpd.CaseDef(pattern, tpd.EmptyTree, rhs)
def copy(original: Tree)(pattern: TypeTree, rhs: TypeTree): TypeCaseDef =
tpd.cpy.CaseDef(original)(pattern, tpd.EmptyTree, rhs)
def unapply(tree: TypeCaseDef): (TypeTree, TypeTree) =
(tree.pat, tree.body)
end TypeCaseDef
given TypeCaseDefMethods: TypeCaseDefMethods with
extension (self: TypeCaseDef)
def pattern: TypeTree = self.pat
def rhs: TypeTree = self.body
end extension
end TypeCaseDefMethods
type Bind = tpd.Bind
object BindTypeTest extends TypeTest[Tree, Bind]:
def unapply(x: Tree): Option[Bind & x.type] = x match
case x: (tpd.Bind & x.type) if x.name.isTermName => Some(x)
case _ => None
end BindTypeTest
object Bind extends BindModule:
def apply(sym: Symbol, pattern: Tree): Bind =
xCheckMacroAssert(sym.flags.is(Flags.Case), "expected a symbol with `Case` flag set")
withDefaultPos(tpd.Bind(sym, pattern))
def copy(original: Tree)(name: String, pattern: Tree): Bind =
withDefaultPos(tpd.cpy.Bind(original)(name.toTermName, pattern))
def unapply(pattern: Bind): (String, Tree) =
(pattern.name.toString, pattern.pattern)
end Bind
given BindMethods: BindMethods with
extension (self: Bind)
def name: String = self.name.toString
def pattern: Tree = self.body
end extension
end BindMethods
type Unapply = tpd.UnApply
object UnapplyTypeTest extends TypeTest[Tree, Unapply]:
def unapply(x: Tree): Option[Unapply & x.type] = x match
case x: (tpd.UnApply & x.type) => Some(x)
case _ => None
end UnapplyTypeTest
object Unapply extends UnapplyModule:
def apply(fun: Term, implicits: List[Term], patterns: List[Tree]): Unapply =
withDefaultPos(tpd.UnApply(fun, implicits, patterns, dotc.core.Symbols.defn.NothingType))
def copy(original: Tree)(fun: Term, implicits: List[Term], patterns: List[Tree]): Unapply =
withDefaultPos(tpd.cpy.UnApply(original)(fun, implicits, patterns))
def unapply(x: Unapply): (Term, List[Term], List[Tree]) =
(x.fun, x.implicits, x.patterns)
end Unapply
given UnapplyMethods: UnapplyMethods with
extension (self: Unapply)
def fun: Term = self.fun
def implicits: List[Term] = self.implicits
def patterns: List[Tree] = effectivePatterns(self.patterns)
end extension
private def effectivePatterns(patterns: List[Tree]): List[Tree] =
patterns match
case patterns0 :+ dotc.ast.Trees.SeqLiteral(elems, _) => patterns0 ::: elems
case _ => patterns
end UnapplyMethods
type Alternatives = tpd.Alternative
object AlternativesTypeTest extends TypeTest[Tree, Alternatives]:
def unapply(x: Tree): Option[Alternatives & x.type] = x match
case x: (tpd.Alternative & x.type) => Some(x)
case _ => None
end AlternativesTypeTest
object Alternatives extends AlternativesModule:
def apply(patterns: List[Tree]): Alternatives =
withDefaultPos(tpd.Alternative(patterns))
def copy(original: Tree)(patterns: List[Tree]): Alternatives =
tpd.cpy.Alternative(original)(patterns)
def unapply(x: Alternatives): Some[List[Tree]] =
Some(x.patterns)
end Alternatives
given AlternativesMethods: AlternativesMethods with
extension (self: Alternatives)
def patterns: List[Tree] = self.trees
end extension
end AlternativesMethods
type ParamClause = tpd.ParamClause
object ParamClause extends ParamClauseModule
given ParamClauseMethods: ParamClauseMethods with
extension (self: ParamClause)
def params: List[ValDef] | List[TypeDef] = self
end ParamClauseMethods
type TermParamClause = List[tpd.ValDef]
given TermParamClauseTypeTest: TypeTest[ParamClause, TermParamClause] with
def unapply(x: ParamClause): Option[TermParamClause & x.type] = x match
case tpd.ValDefs(_) => Some(x.asInstanceOf[TermParamClause & x.type])
case _ => None
end TermParamClauseTypeTest
object TermParamClause extends TermParamClauseModule:
def apply(params: List[ValDef]): TermParamClause =
if xCheckMacro then
val implicitParams = params.count(_.symbol.is(dotc.core.Flags.Implicit))
assert(implicitParams == 0 || implicitParams == params.size, "Expected all or non of parameters to be implicit")
params
def unapply(x: TermParamClause): Some[List[ValDef]] = Some(x)
end TermParamClause
given TermParamClauseMethods: TermParamClauseMethods with
extension (self: TermParamClause)
def params: List[ValDef] = self
def isImplicit: Boolean =
self.nonEmpty && self.head.symbol.is(dotc.core.Flags.Implicit)
def isGiven: Boolean =
self.nonEmpty && self.head.symbol.is(dotc.core.Flags.Given)
def isErased: Boolean = false
def erasedArgs: List[Boolean] =
self.map(_.symbol.is(dotc.core.Flags.Erased))
def hasErasedArgs: Boolean =
self.exists(_.symbol.is(dotc.core.Flags.Erased))
end TermParamClauseMethods
type TypeParamClause = List[tpd.TypeDef]
given TypeParamClauseTypeTest: TypeTest[ParamClause, TypeParamClause] with
def unapply(x: ParamClause): Option[TypeParamClause & x.type] = x match
case tpd.TypeDefs(_) => Some(x.asInstanceOf[TypeParamClause & x.type])
case _ => None
end TypeParamClauseTypeTest
object TypeParamClause extends TypeParamClauseModule:
def apply(params: List[TypeDef]): TypeParamClause =
if params.isEmpty then throw IllegalArgumentException("Empty type parameters")
params
def unapply(x: TypeParamClause): Some[List[TypeDef]] = Some(x)
end TypeParamClause
given TypeParamClauseMethods: TypeParamClauseMethods with
extension (self: TypeParamClause)
def params: List[TypeDef] = self
end TypeParamClauseMethods
type Selector = untpd.ImportSelector
object Selector extends SelectorModule
type SimpleSelector = untpd.ImportSelector
object SimpleSelectorTypeTest extends TypeTest[Selector, SimpleSelector]:
def unapply(x: Selector): Option[SimpleSelector & x.type] = x match
case x: (untpd.ImportSelector & x.type) if x.renamed.isEmpty && !x.isGiven => Some(x)
case _ => None // TODO: handle import bounds
end SimpleSelectorTypeTest
object SimpleSelector extends SimpleSelectorModule:
def unapply(x: SimpleSelector): Some[String] = Some(x.name.toString)
end SimpleSelector
given SimpleSelectorMethods: SimpleSelectorMethods with
extension (self: SimpleSelector)
def name: String = self.imported.name.toString
def namePos: Position = self.imported.sourcePos
end extension
end SimpleSelectorMethods
type RenameSelector = untpd.ImportSelector
object RenameSelectorTypeTest extends TypeTest[Selector, RenameSelector]:
def unapply(x: Selector): Option[RenameSelector & x.type] = x match
case x: (untpd.ImportSelector & x.type) if !x.renamed.isEmpty => Some(x)
case _ => None
end RenameSelectorTypeTest
object RenameSelector extends RenameSelectorModule:
def unapply(x: RenameSelector): (String, String) = (x.fromName, x.toName)
end RenameSelector
given RenameSelectorMethods: RenameSelectorMethods with
extension (self: RenameSelector)
def fromName: String = self.imported.name.toString
def fromPos: Position = self.imported.sourcePos
def toName: String = self.renamed.asInstanceOf[untpd.Ident].name.toString
def toPos: Position = self.renamed.asInstanceOf[untpd.Ident].sourcePos
end extension
end RenameSelectorMethods
type OmitSelector = untpd.ImportSelector
object OmitSelectorTypeTest extends TypeTest[Selector, OmitSelector]:
def unapply(x: Selector): Option[OmitSelector & x.type] = x match {
case self: (untpd.ImportSelector & x.type) =>
self.renamed match
case dotc.ast.Trees.Ident(nme.WILDCARD) => Some(self)
case _ => None
case _ => None
}
end OmitSelectorTypeTest
object OmitSelector extends OmitSelectorModule:
def unapply(x: OmitSelector): Some[String] = Some(x.imported.name.toString)
end OmitSelector
given OmitSelectorMethods: OmitSelectorMethods with
extension (self: OmitSelector)
def name: String = self.imported.toString
def namePos: Position = self.imported.sourcePos
end extension
end OmitSelectorMethods
type GivenSelector = untpd.ImportSelector
object GivenSelectorTypeTest extends TypeTest[Selector, GivenSelector]:
def unapply(x: Selector): Option[GivenSelector & x.type] = x match {
case self: (untpd.ImportSelector & x.type) if x.isGiven => Some(self)
case _ => None
}
end GivenSelectorTypeTest
object GivenSelector extends GivenSelectorModule:
def unapply(x: GivenSelector): Some[Option[TypeTree]] =
Some(GivenSelectorMethods.bound(x))
end GivenSelector
given GivenSelectorMethods: GivenSelectorMethods with
extension (self: GivenSelector)
def bound: Option[TypeTree] =
self.bound match
case untpd.TypedSplice(tpt) => Some(tpt)
case _ => None
end extension
end GivenSelectorMethods
type TypeRepr = dotc.core.Types.Type
object TypeRepr extends TypeReprModule:
def of[T <: AnyKind](using tp: scala.quoted.Type[T]): TypeRepr =
tp.asInstanceOf[TypeImpl].typeTree.tpe
def typeConstructorOf(clazz: Class[?]): TypeRepr =
if (clazz.isPrimitive)
if (clazz == classOf[Boolean]) dotc.core.Symbols.defn.BooleanType
else if (clazz == classOf[Byte]) dotc.core.Symbols.defn.ByteType
else if (clazz == classOf[Char]) dotc.core.Symbols.defn.CharType
else if (clazz == classOf[Short]) dotc.core.Symbols.defn.ShortType
else if (clazz == classOf[Int]) dotc.core.Symbols.defn.IntType
else if (clazz == classOf[Long]) dotc.core.Symbols.defn.LongType
else if (clazz == classOf[Float]) dotc.core.Symbols.defn.FloatType
else if (clazz == classOf[Double]) dotc.core.Symbols.defn.DoubleType
else dotc.core.Symbols.defn.UnitType
else if (clazz.isArray)
dotc.core.Symbols.defn.ArrayType.appliedTo(typeConstructorOf(clazz.getComponentType))
else if clazz.isMemberClass then
val name = clazz.getSimpleName.toTypeName
val enclosing = typeConstructorOf(clazz.getEnclosingClass)
if (enclosing.member(name).exists) enclosing.select(name)
else enclosing.classSymbol.companionModule.termRef.select(name)
else
dotc.core.Symbols.getClassIfDefined(clazz.getCanonicalName).typeRef
end TypeRepr
given TypeReprMethods: TypeReprMethods with
extension (self: TypeRepr)
def show(using printer: Printer[TypeRepr]): String = printer.show(self)
def seal: scala.quoted.Type[_] = self.asType
def asType: scala.quoted.Type[?] =
new TypeImpl(Inferred(self), SpliceScope.getCurrent)
def =:=(that: TypeRepr): Boolean = self =:= that
def <:<(that: TypeRepr): Boolean = self <:< that
def widen: TypeRepr = self.widen
def widenTermRefByName: TypeRepr =
self.widenTermRefExpr match
case dotc.core.Types.ClassInfo(prefix, sym, _, _, _) => prefix.select(sym)
case other => other
def widenByName: TypeRepr = self.widenExpr
def dealias: TypeRepr = self.dealias
def simplified: TypeRepr = self.simplified
def classSymbol: Option[Symbol] =
if self.classSymbol.exists then Some(self.classSymbol.asClass)
else None
def typeSymbol: Symbol = self.typeSymbol
def termSymbol: Symbol = self.termSymbol
def isSingleton: Boolean = self.isSingleton
def memberType(member: Symbol): TypeRepr =
member.info.asSeenFrom(self, member.owner)
def baseClasses: List[Symbol] = self.baseClasses
def baseType(cls: Symbol): TypeRepr = self.baseType(cls)
def derivesFrom(cls: Symbol): Boolean = self.derivesFrom(cls)
def isFunctionType: Boolean =
dotc.core.Symbols.defn.isFunctionNType(self)
def isContextFunctionType: Boolean =
dotc.core.Symbols.defn.isContextFunctionType(self)
def isErasedFunctionType: Boolean =
self.derivesFrom(dotc.core.Symbols.defn.ErasedFunctionClass)
def isDependentFunctionType: Boolean =
val tpNoRefinement = self.dropDependentRefinement
tpNoRefinement != self
&& dotc.core.Symbols.defn.isNonRefinedFunction(tpNoRefinement)
def isTupleN: Boolean =
dotc.core.Symbols.defn.isTupleNType(self)
def select(sym: Symbol): TypeRepr = self.select(sym)
def appliedTo(targ: TypeRepr): TypeRepr =
dotc.core.Types.decorateTypeApplications(self).appliedTo(targ)
def appliedTo(targs: List[TypeRepr]): TypeRepr =
dotc.core.Types.decorateTypeApplications(self).appliedTo(targs)
def substituteTypes(from: List[Symbol], to: List[TypeRepr]): TypeRepr =
self.subst(from, to)
def typeArgs: List[TypeRepr] = self match
case AppliedType(_, args) => args
case _ => List.empty
end extension
end TypeReprMethods
type ConstantType = dotc.core.Types.ConstantType
object ConstantTypeTypeTest extends TypeTest[TypeRepr, ConstantType]:
def unapply(x: TypeRepr): Option[ConstantType & x.type] = x match
case tpe: (Types.ConstantType & x.type) => Some(tpe)
case _ => None
end ConstantTypeTypeTest
object ConstantType extends ConstantTypeModule:
def apply(const: Constant): ConstantType = Types.ConstantType(const)
def unapply(x: ConstantType): Some[Constant] = Some(x.constant)
end ConstantType
given ConstantTypeMethods: ConstantTypeMethods with
extension (self: ConstantType) def constant: Constant = self.value
end ConstantTypeMethods
type NamedType = dotc.core.Types.NamedType
object NamedTypeTypeTest extends TypeTest[TypeRepr, NamedType]:
def unapply(x: TypeRepr): Option[NamedType & x.type] = x match
case tpe: (Types.NamedType & x.type) => Some(tpe)
case _ => None
end NamedTypeTypeTest
given NamedTypeMethods: NamedTypeMethods with
extension (self: NamedType)
def qualifier: TypeRepr = self.prefix.widenSkolem
def name: String = self.name.toString
end extension
end NamedTypeMethods
type TermRef = dotc.core.Types.NamedType
object TermRefTypeTest extends TypeTest[TypeRepr, TermRef]:
def unapply(x: TypeRepr): Option[TermRef & x.type] = x match
case tpe: (Types.TermRef & x.type) => Some(tpe)
case _ => None
end TermRefTypeTest
object TermRef extends TermRefModule:
def apply(qual: TypeRepr, name: String): TermRef =
Types.TermRef(qual, name.toTermName)
def unapply(x: TermRef): (TypeRepr, String) =
(x.prefix, x.name.toString)
end TermRef
type TypeRef = dotc.core.Types.TypeRef
object TypeRefTypeTest extends TypeTest[TypeRepr, TypeRef]:
def unapply(x: TypeRepr): Option[TypeRef & x.type] = x match
case tpe: (Types.TypeRef & x.type) => Some(tpe)
case _ => None
end TypeRefTypeTest
object TypeRef extends TypeRefModule:
def unapply(x: TypeRef): (TypeRepr, String) =
(x.prefix, x.name.toString)
end TypeRef
given TypeRefMethods: TypeRefMethods with
extension (self: TypeRef)
def isOpaqueAlias: Boolean = self.symbol.isOpaqueAlias
def translucentSuperType: TypeRepr = self.translucentSuperType
end extension
end TypeRefMethods
type SuperType = dotc.core.Types.SuperType
object SuperTypeTypeTest extends TypeTest[TypeRepr, SuperType]:
def unapply(x: TypeRepr): Option[SuperType & x.type] = x match
case tpe: (Types.SuperType & x.type) => Some(tpe)
case _ => None
end SuperTypeTypeTest
object SuperType extends SuperTypeModule:
def apply(thistpe: TypeRepr, supertpe: TypeRepr): SuperType =
Types.SuperType(thistpe, supertpe)
def unapply(x: SuperType): (TypeRepr, TypeRepr) =
(x.thistpe, x.supertpe)
end SuperType
given SuperTypeMethods: SuperTypeMethods with
extension (self: SuperType)
def thistpe: TypeRepr = self.thistpe
def supertpe: TypeRepr = self.thistpe
end extension
end SuperTypeMethods
type Refinement = dotc.core.Types.RefinedType
object RefinementTypeTest extends TypeTest[TypeRepr, Refinement]:
def unapply(x: TypeRepr): Option[Refinement & x.type] = x match
case tpe: (Types.RefinedType & x.type) => Some(tpe)
case _ => None
end RefinementTypeTest
object Refinement extends RefinementModule:
def apply(parent: TypeRepr, name: String, info: TypeRepr): Refinement =
val name1 =
info match
case _: TypeBounds => name.toTypeName
case _ => name.toTermName
Types.RefinedType(parent, name1, info)
def unapply(x: Refinement): (TypeRepr, String, TypeRepr) =
(x.parent, x.name, x.info)
end Refinement
given RefinementMethods: RefinementMethods with
extension (self: Refinement)
def parent: TypeRepr = self.parent
def name: String = self.refinedName.toString
def info: TypeRepr = self.refinedInfo
end extension
end RefinementMethods
type AppliedType = dotc.core.Types.AppliedType
object AppliedTypeTypeTest extends TypeTest[TypeRepr, AppliedType]:
def unapply(x: TypeRepr): Option[AppliedType & x.type] = x match
case tpe: (Types.AppliedType & x.type) if !tpe.tycon.isRef(dotc.core.Symbols.defn.MatchCaseClass) => Some(tpe)
case _ => None
end AppliedTypeTypeTest
object AppliedType extends AppliedTypeModule:
def apply(tycon: TypeRepr, args: List[TypeRepr]): AppliedType =
Types.AppliedType(tycon, args)
def unapply(x: AppliedType): (TypeRepr, List[TypeRepr]) =
(AppliedTypeMethods.tycon(x), AppliedTypeMethods.args(x))
end AppliedType
given AppliedTypeMethods: AppliedTypeMethods with
extension (self: AppliedType)
def tycon: TypeRepr = self.tycon.stripTypeVar
def args: List[TypeRepr] = self.args.mapConserve(_.stripTypeVar)
end extension
end AppliedTypeMethods
type AnnotatedType = dotc.core.Types.AnnotatedType
object AnnotatedTypeTypeTest extends TypeTest[TypeRepr, AnnotatedType]:
def unapply(x: TypeRepr): Option[AnnotatedType & x.type] = x match
case tpe: (Types.AnnotatedType & x.type) => Some(tpe)
case _ => None
end AnnotatedTypeTypeTest
object AnnotatedType extends AnnotatedTypeModule:
def apply(underlying: TypeRepr, annot: Term): AnnotatedType =
Types.AnnotatedType(underlying, Annotations.Annotation(annot))
def unapply(x: AnnotatedType): (TypeRepr, Term) =
(x.underlying.stripTypeVar, x.annot.tree)
end AnnotatedType
given AnnotatedTypeMethods: AnnotatedTypeMethods with
extension (self: AnnotatedType)
def underlying: TypeRepr = self.underlying.stripTypeVar
def annotation: Term = self.annot.tree
end extension
end AnnotatedTypeMethods
type AndOrType = dotc.core.Types.AndOrType
object AndOrTypeTypeTest extends TypeTest[TypeRepr, AndOrType]:
def unapply(x: TypeRepr): Option[AndOrType & x.type] = x match
case tpe: (Types.AndOrType & x.type) => Some(tpe)
case _ => None
end AndOrTypeTypeTest
given AndOrTypeMethods: AndOrTypeMethods with
extension (self: AndOrType)
def left: TypeRepr = self.tp1.stripTypeVar
def right: TypeRepr = self.tp2.stripTypeVar
end extension
end AndOrTypeMethods
type AndType = dotc.core.Types.AndType
object AndTypeTypeTest extends TypeTest[TypeRepr, AndType]:
def unapply(x: TypeRepr): Option[AndType & x.type] = x match
case tpe: (Types.AndType & x.type) => Some(tpe)
case _ => None
end AndTypeTypeTest
object AndType extends AndTypeModule:
def apply(lhs: TypeRepr, rhs: TypeRepr): AndType = Types.AndType(lhs, rhs)
def unapply(x: AndType): (TypeRepr, TypeRepr) = (x.left, x.right)
end AndType
type OrType = dotc.core.Types.OrType
object OrTypeTypeTest extends TypeTest[TypeRepr, OrType]:
def unapply(x: TypeRepr): Option[OrType & x.type] = x match
case tpe: (Types.OrType & x.type) => Some(tpe)
case _ => None
end OrTypeTypeTest
object OrType extends OrTypeModule:
def apply(lhs: TypeRepr, rhs: TypeRepr): OrType = Types.OrType(lhs, rhs, soft = false)
def unapply(x: OrType): (TypeRepr, TypeRepr) = (x.left, x.right)
end OrType
type MatchType = dotc.core.Types.MatchType
object MatchTypeTypeTest extends TypeTest[TypeRepr, MatchType]:
def unapply(x: TypeRepr): Option[MatchType & x.type] = x match
case tpe: (Types.MatchType & x.type) => Some(tpe)
case _ => None
end MatchTypeTypeTest
object MatchType extends MatchTypeModule:
def apply(bound: TypeRepr, scrutinee: TypeRepr, cases: List[TypeRepr]): MatchType =
Types.MatchType(bound, scrutinee, cases)
def unapply(x: MatchType): (TypeRepr, TypeRepr, List[TypeRepr]) =
(x.bound, x.scrutinee, x.cases)
end MatchType
given MatchTypeMethods: MatchTypeMethods with
extension (self: MatchType)
def bound: TypeRepr = self.bound
def scrutinee: TypeRepr = self.scrutinee
def cases: List[TypeRepr] = self.cases
end extension
end MatchTypeMethods
type ByNameType = dotc.core.Types.ExprType
object ByNameTypeTypeTest extends TypeTest[TypeRepr, ByNameType]:
def unapply(x: TypeRepr): Option[ByNameType & x.type] = x match
case tpe: (Types.ExprType & x.type) => Some(tpe)
case _ => None
end ByNameTypeTypeTest
object ByNameType extends ByNameTypeModule:
def apply(underlying: TypeRepr): TypeRepr = Types.ExprType(underlying)
def unapply(x: ByNameType): Some[TypeRepr] = Some(x.underlying)
end ByNameType
given ByNameTypeMethods: ByNameTypeMethods with
extension (self: ByNameType)
def underlying: TypeRepr = self.resType.stripTypeVar
end extension
end ByNameTypeMethods
type ParamRef = dotc.core.Types.ParamRef
object ParamRefTypeTest extends TypeTest[TypeRepr, ParamRef]:
def unapply(x: TypeRepr): Option[ParamRef & x.type] = x match
case tpe: (Types.TypeParamRef & x.type) => Some(tpe)
case tpe: (Types.TermParamRef & x.type) => Some(tpe)
case _ => None
end ParamRefTypeTest
object ParamRef extends ParamRefModule:
def unapply(x: ParamRef): (LambdaType, Int) =
(x.binder, x.paramNum)
end ParamRef
given ParamRefMethods: ParamRefMethods with
extension (self: ParamRef)
def binder: LambdaType = self.binder.asInstanceOf[LambdaType] // Cast to tpd
def paramNum: Int = self.paramNum
end extension
end ParamRefMethods
type ThisType = dotc.core.Types.ThisType
object ThisTypeTypeTest extends TypeTest[TypeRepr, ThisType]:
def unapply(x: TypeRepr): Option[ThisType & x.type] = x match
case tpe: (Types.ThisType & x.type) => Some(tpe)
case _ => None
end ThisTypeTypeTest
object ThisType extends ThisTypeModule:
def unapply(x: ThisType): Some[TypeRepr] = Some(x.tref)
end ThisType
given ThisTypeMethods: ThisTypeMethods with
extension (self: ThisType)
def tref: TypeRepr = self.tref
end extension
end ThisTypeMethods
type RecursiveThis = dotc.core.Types.RecThis
object RecursiveThisTypeTest extends TypeTest[TypeRepr, RecursiveThis]:
def unapply(x: TypeRepr): Option[RecursiveThis & x.type] = x match
case tpe: (Types.RecThis & x.type) => Some(tpe)
case _ => None
end RecursiveThisTypeTest
object RecursiveThis extends RecursiveThisModule:
def unapply(x: RecursiveThis): Some[RecursiveType] = Some(x.binder)
end RecursiveThis
given RecursiveThisMethods: RecursiveThisMethods with
extension (self: RecursiveThis)
def binder: RecursiveType = self.binder
end extension
end RecursiveThisMethods
type RecursiveType = dotc.core.Types.RecType
object RecursiveTypeTypeTest extends TypeTest[TypeRepr, RecursiveType]:
def unapply(x: TypeRepr): Option[RecursiveType & x.type] = x match
case tpe: (Types.RecType & x.type) => Some(tpe)
case _ => None
end RecursiveTypeTypeTest
object RecursiveType extends RecursiveTypeModule:
def apply(parentExp: RecursiveType => TypeRepr): RecursiveType =
Types.RecType(parentExp)
def unapply(x: RecursiveType): Some[TypeRepr] = Some(x.underlying)
end RecursiveType
given RecursiveTypeMethods: RecursiveTypeMethods with
extension (self: RecursiveType)
def underlying: TypeRepr = self.underlying.stripTypeVar
def recThis: RecursiveThis = self.recThis
end extension
end RecursiveTypeMethods
type LambdaType = dotc.core.Types.LambdaType
object LambdaTypeTypeTest extends TypeTest[TypeRepr, LambdaType]:
def unapply(x: TypeRepr): Option[LambdaType & x.type] = x match
case tpe: (Types.LambdaType & x.type) => Some(tpe)
case _ => None
end LambdaTypeTypeTest
given LambdaTypeMethods: LambdaTypeMethods with
extension (self: LambdaType)
def paramNames: List[String] = self.paramNames.map(_.toString)
def paramTypes: List[TypeRepr] = self.paramInfos
def resType: TypeRepr = self.resType
end extension
end LambdaTypeMethods
type MethodOrPoly = dotc.core.Types.MethodOrPoly
object MethodOrPolyTypeTest extends TypeTest[TypeRepr, MethodOrPoly]:
def unapply(x: TypeRepr): Option[MethodOrPoly & x.type] = x match
case tpe: (Types.MethodOrPoly & x.type) => Some(tpe)
case _ => None
end MethodOrPolyTypeTest
type MethodType = dotc.core.Types.MethodType
object MethodTypeTypeTest extends TypeTest[TypeRepr, MethodType]:
def unapply(x: TypeRepr): Option[MethodType & x.type] = x match
case tpe: (Types.MethodType & x.type) => Some(tpe)
case _ => None
end MethodTypeTypeTest
object MethodType extends MethodTypeModule:
def apply(paramNames: List[String])(paramInfosExp: MethodType => List[TypeRepr], resultTypeExp: MethodType => TypeRepr): MethodType =
Types.MethodType(paramNames.map(_.toTermName))(paramInfosExp, resultTypeExp)
def unapply(x: MethodType): (List[String], List[TypeRepr], TypeRepr) =
(x.paramNames.map(_.toString), x.paramTypes, x.resType)
end MethodType
given MethodTypeMethods: MethodTypeMethods with
extension (self: MethodType)
def isErased: Boolean = false
def isImplicit: Boolean = self.isImplicitMethod
def param(idx: Int): TypeRepr = self.newParamRef(idx)
def erasedParams: List[Boolean] = self.erasedParams
def hasErasedParams: Boolean = self.hasErasedParams
end extension
end MethodTypeMethods
type PolyType = dotc.core.Types.PolyType
object PolyTypeTypeTest extends TypeTest[TypeRepr, PolyType]:
def unapply(x: TypeRepr): Option[PolyType & x.type] = x match
case tpe: (Types.PolyType & x.type) => Some(tpe)
case _ => None
end PolyTypeTypeTest
object PolyType extends PolyTypeModule:
def apply(paramNames: List[String])(paramBoundsExp: PolyType => List[TypeBounds], resultTypeExp: PolyType => TypeRepr): PolyType =
Types.PolyType(paramNames.map(_.toTypeName))(paramBoundsExp, resultTypeExp)
def unapply(x: PolyType): (List[String], List[TypeBounds], TypeRepr) =
(x.paramNames.map(_.toString), x.paramBounds, x.resType)
end PolyType
given PolyTypeMethods: PolyTypeMethods with
extension (self: PolyType)
def param(idx: Int): TypeRepr = self.newParamRef(idx)
def paramBounds: List[TypeBounds] = self.paramInfos
end extension
end PolyTypeMethods
type TypeLambda = dotc.core.Types.HKTypeLambda
object TypeLambdaTypeTest extends TypeTest[TypeRepr, TypeLambda]:
def unapply(x: TypeRepr): Option[TypeLambda & x.type] = x match
case tpe: (Types.HKTypeLambda & x.type) => Some(tpe)
case _ => None
end TypeLambdaTypeTest
object TypeLambda extends TypeLambdaModule:
def apply(paramNames: List[String], boundsFn: TypeLambda => List[TypeBounds], bodyFn: TypeLambda => TypeRepr): TypeLambda =
Types.HKTypeLambda(paramNames.map(_.toTypeName))(boundsFn, bodyFn)
def unapply(x: TypeLambda): (List[String], List[TypeBounds], TypeRepr) =
(x.paramNames.map(_.toString), x.paramBounds, x.resType)
end TypeLambda
given TypeLambdaMethods: TypeLambdaMethods with
extension (self: TypeLambda)
def param(idx: Int): TypeRepr = self.newParamRef(idx)
def paramBounds: List[TypeBounds] = self.paramInfos
end extension
end TypeLambdaMethods
type MatchCase = dotc.core.Types.AppliedType
given MatchCaseTypeTest: TypeTest[TypeRepr, MatchCase] with
def unapply(x: TypeRepr): Option[MatchCase & x.type] = x match
case x: (Types.AppliedType & x.type) if x.tycon.isRef(dotc.core.Symbols.defn.MatchCaseClass) => Some(x)
case _ => None
end MatchCaseTypeTest
object MatchCase extends MatchCaseModule:
def apply(pattern: TypeRepr, rhs: TypeRepr): MatchCase =
Types.AppliedType(dotc.core.Symbols.defn.MatchCaseClass.typeRef, List(pattern, rhs))
def unapply(x: MatchCase): (TypeRepr, TypeRepr) = (x.pattern, x.rhs)
end MatchCase
given MatchCaseMethods: MatchCaseMethods with
extension (self: MatchCase)
def pattern: TypeRepr = self.args(0)
def rhs: TypeRepr = self.args(1)
end extension
end MatchCaseMethods
type TypeBounds = dotc.core.Types.TypeBounds
object TypeBoundsTypeTest extends TypeTest[TypeRepr, TypeBounds]:
def unapply(x: TypeRepr): Option[TypeBounds & x.type] = x match
case x: (Types.TypeBounds & x.type) => Some(x)
case _ => None
end TypeBoundsTypeTest
object TypeBounds extends TypeBoundsModule:
def apply(low: TypeRepr, hi: TypeRepr): TypeBounds = Types.TypeBounds(low, hi)
def unapply(x: TypeBounds): (TypeRepr, TypeRepr) = (x.low.stripLazyRef, x.hi.stripLazyRef)
def empty: TypeBounds = Types .TypeBounds.empty
def upper(hi: TypeRepr): TypeBounds = Types .TypeBounds.upper(hi)
def lower(lo: TypeRepr): TypeBounds = Types .TypeBounds.lower(lo)
end TypeBounds
given TypeBoundsMethods: TypeBoundsMethods with
extension (self: TypeBounds)
def low: TypeRepr = self.lo.stripLazyRef
def hi: TypeRepr = self.hi.stripLazyRef
end extension
end TypeBoundsMethods
type NoPrefix = dotc.core.Types.NoPrefix.type
object NoPrefixTypeTest extends TypeTest[TypeRepr, NoPrefix]:
def unapply(x: TypeRepr): Option[NoPrefix & x.type] =
if x == Types.NoPrefix then Some(x.asInstanceOf[NoPrefix & x.type]) else None
end NoPrefixTypeTest
object NoPrefix extends NoPrefixModule:
def unapply(x: NoPrefix): true = true
end NoPrefix
type Constant = dotc.core.Constants.Constant
object Constant extends ConstantModule
given ConstantMethods: ConstantMethods with
extension (self: Constant)
def value: Any = self.value
def show(using printer: Printer[Constant]): String = printer.show(self)
end extension
end ConstantMethods
type BooleanConstant = dotc.core.Constants.Constant
object BooleanConstantTypeTest extends TypeTest[Constant, BooleanConstant]:
def unapply(x: Constant): Option[BooleanConstant & x.type] =
if x.tag == dotc.core.Constants.BooleanTag then Some(x.asInstanceOf[BooleanConstant & x.type]) else None
end BooleanConstantTypeTest
object BooleanConstant extends BooleanConstantModule:
def apply(x: Boolean): BooleanConstant = dotc.core.Constants.Constant(x)
def unapply(constant: BooleanConstant): Some[Boolean] = Some(constant.booleanValue)
end BooleanConstant
type ByteConstant = dotc.core.Constants.Constant
object ByteConstantTypeTest extends TypeTest[Constant, ByteConstant]:
def unapply(x: Constant): Option[ByteConstant & x.type] =
if x.tag == dotc.core.Constants.ByteTag then Some(x.asInstanceOf[ByteConstant & x.type]) else None
end ByteConstantTypeTest
object ByteConstant extends ByteConstantModule:
def apply(x: Byte): ByteConstant = dotc.core.Constants.Constant(x)
def unapply(constant: ByteConstant): Some[Byte] = Some(constant.byteValue)
end ByteConstant
type ShortConstant = dotc.core.Constants.Constant
object ShortConstantTypeTest extends TypeTest[Constant, ShortConstant]:
def unapply(x: Constant): Option[ShortConstant & x.type] =
if x.tag == dotc.core.Constants.ShortTag then Some(x.asInstanceOf[ShortConstant & x.type]) else None
end ShortConstantTypeTest
object ShortConstant extends ShortConstantModule:
def apply(x: Short): ShortConstant = dotc.core.Constants.Constant(x)
def unapply(constant: ShortConstant): Some[Short] = Some(constant.shortValue)
end ShortConstant
type IntConstant = dotc.core.Constants.Constant
object IntConstantTypeTest extends TypeTest[Constant, IntConstant]:
def unapply(x: Constant): Option[IntConstant & x.type] =
if x.tag == dotc.core.Constants.IntTag then Some(x.asInstanceOf[IntConstant & x.type]) else None
end IntConstantTypeTest
object IntConstant extends IntConstantModule:
def apply(x: Int): IntConstant = dotc.core.Constants.Constant(x)
def unapply(constant: IntConstant): Some[Int] = Some(constant.intValue)
end IntConstant
type LongConstant = dotc.core.Constants.Constant
object LongConstantTypeTest extends TypeTest[Constant, LongConstant]:
def unapply(x: Constant): Option[LongConstant & x.type] =
if x.tag == dotc.core.Constants.LongTag then Some(x.asInstanceOf[LongConstant & x.type]) else None
end LongConstantTypeTest
object LongConstant extends LongConstantModule:
def apply(x: Long): LongConstant = dotc.core.Constants.Constant(x)
def unapply(constant: LongConstant): Some[Long] = Some(constant.longValue)
end LongConstant
type FloatConstant = dotc.core.Constants.Constant
object FloatConstantTypeTest extends TypeTest[Constant, FloatConstant]:
def unapply(x: Constant): Option[FloatConstant & x.type] =
if x.tag == dotc.core.Constants.FloatTag then Some(x.asInstanceOf[FloatConstant & x.type]) else None
end FloatConstantTypeTest
object FloatConstant extends FloatConstantModule:
def apply(x: Float): FloatConstant = dotc.core.Constants.Constant(x)
def unapply(constant: FloatConstant): Some[Float] = Some(constant.floatValue)
end FloatConstant
type DoubleConstant = dotc.core.Constants.Constant
object DoubleConstantTypeTest extends TypeTest[Constant, DoubleConstant]:
def unapply(x: Constant): Option[DoubleConstant & x.type] =
if x.tag == dotc.core.Constants.DoubleTag then Some(x.asInstanceOf[DoubleConstant & x.type]) else None
end DoubleConstantTypeTest
object DoubleConstant extends DoubleConstantModule:
def apply(x: Double): DoubleConstant = dotc.core.Constants.Constant(x)
def unapply(constant: DoubleConstant): Some[Double] = Some(constant.doubleValue)
end DoubleConstant
type CharConstant = dotc.core.Constants.Constant
object CharConstantTypeTest extends TypeTest[Constant, CharConstant]:
def unapply(x: Constant): Option[CharConstant & x.type] =
if x.tag == dotc.core.Constants.CharTag then Some(x.asInstanceOf[CharConstant & x.type]) else None
end CharConstantTypeTest
object CharConstant extends CharConstantModule:
def apply(x: Char): CharConstant = dotc.core.Constants.Constant(x)
def unapply(constant: CharConstant): Some[Char] = Some(constant.charValue)
end CharConstant
type StringConstant = dotc.core.Constants.Constant
object StringConstantTypeTest extends TypeTest[Constant, StringConstant]:
def unapply(x: Constant): Option[StringConstant & x.type] =
if x.tag == dotc.core.Constants.StringTag then Some(x.asInstanceOf[StringConstant & x.type]) else None
end StringConstantTypeTest
object StringConstant extends StringConstantModule:
def apply(x: String): StringConstant = dotc.core.Constants.Constant(x)
def unapply(constant: StringConstant): Some[String] = Some(constant.stringValue)
end StringConstant
type UnitConstant = dotc.core.Constants.Constant
object UnitConstantTypeTest extends TypeTest[Constant, UnitConstant]:
def unapply(x: Constant): Option[UnitConstant & x.type] =
if x.tag == dotc.core.Constants.UnitTag then Some(x.asInstanceOf[UnitConstant & x.type]) else None
end UnitConstantTypeTest
object UnitConstant extends UnitConstantModule:
def apply(): UnitConstant = dotc.core.Constants.Constant(())
def unapply(constant: UnitConstant): true = true
end UnitConstant
type NullConstant = dotc.core.Constants.Constant
object NullConstantTypeTest extends TypeTest[Constant, NullConstant]:
def unapply(x: Constant): Option[NullConstant & x.type] =
if x.tag == dotc.core.Constants.NullTag then Some(x.asInstanceOf[NullConstant & x.type]) else None
end NullConstantTypeTest
object NullConstant extends NullConstantModule:
def apply(): NullConstant = dotc.core.Constants.Constant(null)
def unapply(constant: NullConstant): true = true
end NullConstant
type ClassOfConstant = dotc.core.Constants.Constant
object ClassOfConstantTypeTest extends TypeTest[Constant, ClassOfConstant]:
def unapply(x: Constant): Option[ClassOfConstant & x.type] =
if x.tag == dotc.core.Constants.ClazzTag then Some(x.asInstanceOf[ClassOfConstant & x.type]) else None
end ClassOfConstantTypeTest
object ClassOfConstant extends ClassOfConstantModule:
def apply(x: TypeRepr): ClassOfConstant =
// TODO check that the type is a valid class when creating this constant or let Ycheck do it?
dotc.core.Constants.Constant(x)
def unapply(constant: ClassOfConstant): Some[TypeRepr] = Some(constant.typeValue)
end ClassOfConstant
object Implicits extends ImplicitsModule:
def search(tpe: TypeRepr): ImplicitSearchResult =
import tpd.TreeOps
val implicitTree = ctx.typer.inferImplicitArg(tpe, Position.ofMacroExpansion.span)
// Make sure that we do not have any uninstantiated type variables.
// See tests/pos-macros/i16636.
// See tests/pos-macros/exprSummonWithTypeVar with -Xcheck-macros.
dotc.typer.Inferencing.fullyDefinedType(implicitTree.tpe, "", implicitTree)
implicitTree
end Implicits
type ImplicitSearchResult = Tree
type ImplicitSearchSuccess = Tree
object ImplicitSearchSuccessTypeTest extends TypeTest[ImplicitSearchResult, ImplicitSearchSuccess]:
def unapply(x: ImplicitSearchResult): Option[ImplicitSearchSuccess & x.type] =
x.tpe match
case _: dotc.typer.Implicits.SearchFailureType => None
case _ => Some(x)
end ImplicitSearchSuccessTypeTest
given ImplicitSearchSuccessMethods: ImplicitSearchSuccessMethods with
extension (self: ImplicitSearchSuccess)
def tree: Term = self
end extension
end ImplicitSearchSuccessMethods
type ImplicitSearchFailure = Tree
object ImplicitSearchFailureTypeTest extends TypeTest[ImplicitSearchResult, ImplicitSearchFailure]:
def unapply(x: ImplicitSearchResult): Option[ImplicitSearchFailure & x.type] =
x.tpe match
case _: dotc.typer.Implicits.SearchFailureType => Some(x)
case _ => None
end ImplicitSearchFailureTypeTest
given ImplicitSearchFailureMethods: ImplicitSearchFailureMethods with
extension (self: ImplicitSearchFailure)
def explanation: String =
self.tpe.asInstanceOf[dotc.typer.Implicits.SearchFailureType].explanation
end extension
end ImplicitSearchFailureMethods
type DivergingImplicit = Tree
object DivergingImplicitTypeTest extends TypeTest[ImplicitSearchResult, DivergingImplicit]:
def unapply(x: ImplicitSearchResult): Option[DivergingImplicit & x.type] =
x.tpe match
case _: dotc.typer.Implicits.DivergingImplicit => Some(x)
case _ => None
end DivergingImplicitTypeTest
type NoMatchingImplicits = Tree
object NoMatchingImplicitsTypeTest extends TypeTest[ImplicitSearchResult, NoMatchingImplicits]:
def unapply(x: ImplicitSearchResult): Option[NoMatchingImplicits & x.type] =
x.tpe match
case _: dotc.typer.Implicits.NoMatchingImplicits => Some(x)
case _ => None
end NoMatchingImplicitsTypeTest
type AmbiguousImplicits = Tree
object AmbiguousImplicitsTypeTest extends TypeTest[ImplicitSearchResult, AmbiguousImplicits]:
def unapply(x: ImplicitSearchResult): Option[AmbiguousImplicits & x.type] =
x.tpe match
case _: dotc.typer.Implicits.AmbiguousImplicits => Some(x)
case _ => None
end AmbiguousImplicitsTypeTest
type Symbol = dotc.core.Symbols.Symbol
object Symbol extends SymbolModule:
def spliceOwner: Symbol = ctx.owner
def requiredPackage(path: String): Symbol = dotc.core.Symbols.requiredPackage(path)
def requiredClass(path: String): Symbol = dotc.core.Symbols.requiredClass(path)
def requiredModule(path: String): Symbol = dotc.core.Symbols.requiredModule(path)
def requiredMethod(path: String): Symbol = dotc.core.Symbols.requiredMethod(path)
def classSymbol(fullName: String): Symbol = dotc.core.Symbols.requiredClass(fullName)
def newClass(owner: Symbol, name: String, parents: List[TypeRepr], decls: Symbol => List[Symbol], selfType: Option[TypeRepr]): Symbol =
assert(parents.nonEmpty && !parents.head.typeSymbol.is(dotc.core.Flags.Trait), "First parent must be a class")
val cls = dotc.core.Symbols.newNormalizedClassSymbol(
owner,
name.toTypeName,
dotc.core.Flags.EmptyFlags,
parents,
selfType.getOrElse(Types.NoType),
dotc.core.Symbols.NoSymbol)
cls.enter(dotc.core.Symbols.newConstructor(cls, dotc.core.Flags.Synthetic, Nil, Nil))
for sym <- decls(cls) do cls.enter(sym)
cls
def newModule(owner: Symbol, name: String, modFlags: Flags, clsFlags: Flags, parents: List[TypeRepr], decls: Symbol => List[Symbol], privateWithin: Symbol): Symbol =
assert(parents.nonEmpty && !parents.head.typeSymbol.is(dotc.core.Flags.Trait), "First parent must be a class")
assert(!privateWithin.exists || privateWithin.isType, "privateWithin must be a type symbol or `Symbol.noSymbol`")
val mod = dotc.core.Symbols.newNormalizedModuleSymbol(
owner,
name.toTermName,
modFlags | dotc.core.Flags.ModuleValCreationFlags,
clsFlags | dotc.core.Flags.ModuleClassCreationFlags,
parents,
dotc.core.Scopes.newScope,
privateWithin)
val cls = mod.moduleClass.asClass
cls.enter(dotc.core.Symbols.newConstructor(cls, dotc.core.Flags.Synthetic, Nil, Nil))
for sym <- decls(cls) do cls.enter(sym)
mod
def newMethod(owner: Symbol, name: String, tpe: TypeRepr): Symbol =
newMethod(owner, name, tpe, Flags.EmptyFlags, noSymbol)
def newMethod(owner: Symbol, name: String, tpe: TypeRepr, flags: Flags, privateWithin: Symbol): Symbol =
xCheckMacroAssert(!privateWithin.exists || privateWithin.isType, "privateWithin must be a type symbol or `Symbol.noSymbol`")
val privateWithin1 = if privateWithin.isTerm then Symbol.noSymbol else privateWithin
checkValidFlags(flags.toTermFlags, Flags.validMethodFlags)
dotc.core.Symbols.newSymbol(owner, name.toTermName, flags | dotc.core.Flags.Method, tpe, privateWithin1)
def newVal(owner: Symbol, name: String, tpe: TypeRepr, flags: Flags, privateWithin: Symbol): Symbol =
xCheckMacroAssert(!privateWithin.exists || privateWithin.isType, "privateWithin must be a type symbol or `Symbol.noSymbol`")
val privateWithin1 = if privateWithin.isTerm then Symbol.noSymbol else privateWithin
checkValidFlags(flags.toTermFlags, Flags.validValFlags)
dotc.core.Symbols.newSymbol(owner, name.toTermName, flags, tpe, privateWithin1)
def newBind(owner: Symbol, name: String, flags: Flags, tpe: TypeRepr): Symbol =
checkValidFlags(flags.toTermFlags, Flags.validBindFlags)
dotc.core.Symbols.newSymbol(owner, name.toTermName, flags | dotc.core.Flags.Case, tpe)
def noSymbol: Symbol = dotc.core.Symbols.NoSymbol
private inline def checkValidFlags(inline flags: Flags, inline valid: Flags): Unit =
xCheckMacroAssert(
flags <= valid,
s"Received invalid flags. Expected flags ${flags.show} to only contain a subset of ${valid.show}."
)
def freshName(prefix: String): String =
NameKinds.MacroNames.fresh(prefix.toTermName).toString
end Symbol
given SymbolMethods: SymbolMethods with
extension (self: Symbol)
def owner: Symbol = self.denot.owner
def maybeOwner: Symbol = self.denot.maybeOwner
def flags: Flags = self.denot.flags
def privateWithin: Option[TypeRepr] =
val within: Symbol =
self.denot.privateWithin
if (within.exists && !self.is(dotc.core.Flags.Protected)) Some(within.typeRef)
else None
def protectedWithin: Option[TypeRepr] =
val within: Symbol =
self.denot.privateWithin
if (within.exists && self.is(dotc.core.Flags.Protected)) Some(within.typeRef)
else None
def name: String = self.denot.name.toString
def fullName: String = self.denot.fullName.toString
def info: TypeRepr = self.denot.info
def pos: Option[Position] =
if self.exists then
val symPos = self.sourcePos
if symPos.exists then Some(symPos)
else
if xCheckMacro then report.warning(s"Missing symbol position (defaulting to position 0): $self\nThis is a compiler bug. Please report it.")
Some(self.source.atSpan(dotc.util.Spans.Span(0)))
else None
def docstring: Option[String] =
import dotc.core.Comments.docCtx
val docCtx = ctx.docCtx.getOrElse {
throw new RuntimeException(
"DocCtx could not be found and documentations are unavailable. This is a compiler-internal error."
)
}
docCtx.docstring(self).map(_.raw)
def tree: Tree = FromSymbol.definitionFromSym(self)
def hasAnnotation(annotSym: Symbol): Boolean =
self.denot.hasAnnotation(annotSym)
def getAnnotation(annotSym: Symbol): Option[Term] =
self.denot.getAnnotation(annotSym).map(_.tree)
def annotations: List[Term] =
self.denot.annotations.flatMap {
case _: dotc.core.Annotations.BodyAnnotation => Nil
case annot => annot.tree :: Nil
}
def isDefinedInCurrentRun: Boolean =
self.exists && self.topLevelClass.asClass.isDefinedInCurrentRun
def isLocalDummy: Boolean = self.denot.isLocalDummy
def isRefinementClass: Boolean = self.denot.isRefinementClass
def isAliasType: Boolean = self.denot.isAliasType
def isAnonymousClass: Boolean = self.denot.isAnonymousClass
def isAnonymousFunction: Boolean = self.denot.isAnonymousFunction
def isAbstractType: Boolean = self.denot.isAbstractOrParamType
def isClassConstructor: Boolean = self.denot.isClassConstructor
def isType: Boolean = self.isType
def isTerm: Boolean = self.isTerm
def isPackageDef: Boolean = self.is(dotc.core.Flags.Package)
def isClassDef: Boolean = self.isClass
def isTypeDef: Boolean =
self.isType && !self.isClass && !self.is(dotc.core.Flags.Case)
def isValDef: Boolean =
self.isTerm && !self.is(dotc.core.Flags.Method) && !self.is(dotc.core.Flags.Case/*, FIXME add this check and fix sourcecode butNot = Enum | Module*/)
def isDefDef: Boolean = self.is(dotc.core.Flags.Method)
def isBind: Boolean =
self.is(dotc.core.Flags.Case, butNot = dotc.core.Flags.Enum | dotc.core.Flags.Module) && !self.isClass
def isNoSymbol: Boolean = self == Symbol.noSymbol
def exists: Boolean = self != Symbol.noSymbol
def declaredField(name: String): Symbol =
val sym = self.unforcedDecls.find(sym => sym.name == name.toTermName)
if (isField(sym)) sym else dotc.core.Symbols.NoSymbol
def declaredFields: List[Symbol] = self.unforcedDecls.filter(isField)
/** The prefix on which a member lookup should be performed. */
private def lookupPrefix: TypeRepr =
if self.isClass then
self.thisType // Needed to handle self-types (as in tests/run-macros/self)
else
self.namedType
def memberField(name: String): Symbol = fieldMember(name)
def fieldMember(name: String): Symbol =
lookupPrefix.allMembers.iterator.map(_.symbol).find {
sym => isField(sym) && sym.name.toString == name
}.getOrElse(dotc.core.Symbols.NoSymbol)
def memberFields: List[Symbol] = fieldMembers
def fieldMembers: List[Symbol] =
lookupPrefix.allMembers.iterator.map(_.symbol).collect {
case sym if isField(sym) => sym.asTerm
}.toList
def declaredMethod(name: String): List[Symbol] =
self.typeRef.decls.iterator.collect {
case sym if isMethod(sym) && sym.name.toString == name => sym.asTerm
}.toList
def declaredMethods: List[Symbol] =
self.typeRef.decls.iterator.collect {
case sym if isMethod(sym) => sym.asTerm
}.toList
def memberMethod(name: String): List[Symbol] = methodMember(name)
def methodMember(name: String): List[Symbol] =
lookupPrefix.allMembers.iterator.map(_.symbol).collect {
case sym if isMethod(sym) && sym.name.toString == name => sym.asTerm
}.toList
def memberMethods: List[Symbol] = methodMembers
def methodMembers: List[Symbol] =
lookupPrefix.allMembers.iterator.map(_.symbol).collect {
case sym if isMethod(sym) => sym.asTerm
}.toList
def declaredType(name: String): List[Symbol] =
self.typeRef.decls.iterator.collect {
case sym if sym.isType && sym.name.toString == name => sym.asType
}.toList
def declaredTypes: List[Symbol] =
self.typeRef.decls.iterator.collect {
case sym if sym.isType => sym.asType
}.toList
def memberType(name: String): Symbol =
self.typeRef.decls.find(sym => sym.name == name.toTypeName)
def typeMember(name: String): Symbol =
lookupPrefix.member(name.toTypeName).symbol
def memberTypes: List[Symbol] =
self.typeRef.decls.filter(_.isType)
def typeMembers: List[Symbol] =
lookupPrefix.typeMembers.map(_.symbol).toList
def declarations: List[Symbol] =
self.typeRef.info.decls.toList
def paramSymss: List[List[Symbol]] = self.denot.paramSymss
def primaryConstructor: Symbol = self.denot.primaryConstructor
def allOverriddenSymbols: Iterator[Symbol] = self.denot.allOverriddenSymbols
def overridingSymbol(ofclazz: Symbol): Symbol =
if ofclazz.isClass then self.denot.overridingSymbol(ofclazz.asClass)
else dotc.core.Symbols.NoSymbol
def caseFields: List[Symbol] =
if !self.isClass then Nil
else self.asClass.paramAccessors.collect {
case sym if sym.is(dotc.core.Flags.CaseAccessor) => sym.asTerm
}
def isTypeParam: Boolean = self.isTypeParam
def signature: Signature = self.signature
def moduleClass: Symbol = self.denot.moduleClass
def companionClass: Symbol = self.denot.companionClass
def companionModule: Symbol = self.denot.companionModule
def children: List[Symbol] = self.denot.children
def typeRef: TypeRef = self.denot.typeRef
def termRef: TermRef = self.denot.termRef
def show(using printer: Printer[Symbol]): String = printer.show(self)
def asQuotes: Nested =
assert(self.ownersIterator.contains(ctx.owner), s"$self is not owned by ${ctx.owner}")
new QuotesImpl(using ctx.withOwner(self))
end extension
private def appliedTypeRef(sym: Symbol): TypeRepr =
sym.typeRef.appliedTo(sym.typeParams.map(_.typeRef))
private def isMethod(sym: Symbol): Boolean =
sym.isTerm && sym.is(dotc.core.Flags.Method) && !sym.isConstructor
private def isField(sym: Symbol): Boolean =
sym.isTerm && !sym.is(dotc.core.Flags.Method)
end SymbolMethods
type Signature = dotc.core.Signature
object Signature extends SignatureModule:
def unapply(sig: Signature): (List[String | Int], String) =
(sig.paramSigs, sig.resultSig)
end Signature
given SignatureMethods: SignatureMethods with
extension (self: Signature)
def paramSigs: List[String | Int] =
self.paramsSig.map {
case paramSig: dotc.core.Names.TypeName =>
paramSig.toString
case paramSig: Int =>
paramSig
}
def resultSig: String =
self.resSig.toString
end extension
end SignatureMethods
object defn extends defnModule:
def RootPackage: Symbol = dotc.core.Symbols.defn.RootPackage
def RootClass: Symbol = dotc.core.Symbols.defn.RootClass
def EmptyPackageClass: Symbol = dotc.core.Symbols.defn.EmptyPackageClass
def ScalaPackage: Symbol = dotc.core.Symbols.defn.ScalaPackageVal
def ScalaPackageClass: Symbol = dotc.core.Symbols.defn.ScalaPackageClass
def AnyClass: Symbol = dotc.core.Symbols.defn.AnyClass
def MatchableClass: Symbol = dotc.core.Symbols.defn.MatchableClass
def AnyValClass: Symbol = dotc.core.Symbols.defn.AnyValClass
def ObjectClass: Symbol = dotc.core.Symbols.defn.ObjectClass
def AnyRefClass: Symbol = dotc.core.Symbols.defn.AnyRefAlias
def NullClass: Symbol = dotc.core.Symbols.defn.NullClass
def NothingClass: Symbol = dotc.core.Symbols.defn.NothingClass
def UnitClass: Symbol = dotc.core.Symbols.defn.UnitClass
def ByteClass: Symbol = dotc.core.Symbols.defn.ByteClass
def ShortClass: Symbol = dotc.core.Symbols.defn.ShortClass
def CharClass: Symbol = dotc.core.Symbols.defn.CharClass
def IntClass: Symbol = dotc.core.Symbols.defn.IntClass
def LongClass: Symbol = dotc.core.Symbols.defn.LongClass
def FloatClass: Symbol = dotc.core.Symbols.defn.FloatClass
def DoubleClass: Symbol = dotc.core.Symbols.defn.DoubleClass
def BooleanClass: Symbol = dotc.core.Symbols.defn.BooleanClass
def StringClass: Symbol = dotc.core.Symbols.defn.StringClass
def ClassClass: Symbol = dotc.core.Symbols.defn.ClassClass
def ArrayClass: Symbol = dotc.core.Symbols.defn.ArrayClass
def PredefModule: Symbol = dotc.core.Symbols.defn.ScalaPredefModule
def Predef_classOf: Symbol = dotc.core.Symbols.defn.Predef_classOf
def JavaLangPackage: Symbol = dotc.core.Symbols.defn.JavaLangPackageVal
def ArrayModule: Symbol = dotc.core.Symbols.defn.ArrayModule
def Array_apply: Symbol = dotc.core.Symbols.defn.Array_apply
def Array_clone: Symbol = dotc.core.Symbols.defn.Array_clone
def Array_length: Symbol = dotc.core.Symbols.defn.Array_length
def Array_update: Symbol = dotc.core.Symbols.defn.Array_update
def RepeatedParamClass: Symbol = dotc.core.Symbols.defn.RepeatedParamClass
def RepeatedAnnot: Symbol = dotc.core.Symbols.defn.RepeatedAnnot
def OptionClass: Symbol = dotc.core.Symbols.defn.OptionClass
def NoneModule: Symbol = dotc.core.Symbols.defn.NoneModule
def SomeModule: Symbol = dotc.core.Symbols.defn.SomeClass.companionModule
def ProductClass: Symbol = dotc.core.Symbols.defn.ProductClass
def FunctionClass(arity: Int, isImplicit: Boolean = false, isErased: Boolean = false): Symbol =
if arity < 0 then throw IllegalArgumentException(s"arity: $arity")
if isErased then
throw new Exception("Erased function classes are not supported. Use a refined `scala.runtime.ErasedFunction`")
else dotc.core.Symbols.defn.FunctionSymbol(arity, isImplicit)
def ErasedFunctionClass = dotc.core.Symbols.defn.ErasedFunctionClass
def TupleClass(arity: Int): Symbol =
dotc.core.Symbols.defn.TupleType(arity).nn.classSymbol.asClass
def isTupleClass(sym: Symbol): Boolean =
dotc.core.Symbols.defn.isTupleClass(sym)
def ScalaPrimitiveValueClasses: List[Symbol] =
UnitClass :: BooleanClass :: ScalaNumericValueClasses
def ScalaNumericValueClasses: List[Symbol] =
ByteClass :: ShortClass :: IntClass :: LongClass :: FloatClass :: DoubleClass :: CharClass :: Nil
end defn
type Flags = dotc.core.Flags.FlagSet
object Flags extends FlagsModule:
def Abstract: Flags = dotc.core.Flags.Abstract
def AbsOverride: Flags = dotc.core.Flags.AbsOverride
def Artifact: Flags = dotc.core.Flags.Artifact
def Case: Flags = dotc.core.Flags.Case
def CaseAccessor: Flags = dotc.core.Flags.CaseAccessor
def Contravariant: Flags = dotc.core.Flags.Contravariant
def Covariant: Flags = dotc.core.Flags.Covariant
def Deferred: Flags = dotc.core.Flags.Deferred
def EmptyFlags = dotc.core.Flags.EmptyFlags
def Enum: Flags = dotc.core.Flags.Enum
def Erased: Flags = dotc.core.Flags.Erased
def Exported: Flags = dotc.core.Flags.Exported
def ExtensionMethod: Flags = dotc.core.Flags.ExtensionMethod
def FieldAccessor: Flags = dotc.core.Flags.Accessor
def Final: Flags = dotc.core.Flags.Final
def Given: Flags = dotc.core.Flags.Given
def HasDefault: Flags = dotc.core.Flags.HasDefault
def Implicit: Flags = dotc.core.Flags.Implicit
def Infix: Flags = dotc.core.Flags.Infix
def Inline: Flags = dotc.core.Flags.Inline
def Invisible: Flags = dotc.core.Flags.Invisible
def JavaDefined: Flags = dotc.core.Flags.JavaDefined
def JavaStatic: Flags = dotc.core.Flags.JavaStatic
def JavaAnnotation: Flags = dotc.core.Flags.JavaAnnotation
def Lazy: Flags = dotc.core.Flags.Lazy
def Local: Flags = dotc.core.Flags.Local
def Macro: Flags = dotc.core.Flags.Macro
def Method: Flags = dotc.core.Flags.Method
def Module: Flags = dotc.core.Flags.Module
def Mutable: Flags = dotc.core.Flags.Mutable
def NoInits: Flags = dotc.core.Flags.NoInits
def Opaque: Flags = dotc.core.Flags.Opaque
def Open: Flags = dotc.core.Flags.Open
def Override: Flags = dotc.core.Flags.Override
def Package: Flags = dotc.core.Flags.Package
def Param: Flags = dotc.core.Flags.Param
def ParamAccessor: Flags = dotc.core.Flags.ParamAccessor
def Private: Flags = dotc.core.Flags.Private
def PrivateLocal: Flags = dotc.core.Flags.PrivateLocal
def Protected: Flags = dotc.core.Flags.Protected
def Scala2x: Flags = dotc.core.Flags.Scala2x
def Sealed: Flags = dotc.core.Flags.Sealed
def StableRealizable: Flags = dotc.core.Flags.StableRealizable
@deprecated("Use JavaStatic instead", "3.3.0") def Static: Flags = dotc.core.Flags.JavaStatic
def Synthetic: Flags = dotc.core.Flags.Synthetic
def Trait: Flags = dotc.core.Flags.Trait
def Transparent: Flags = dotc.core.Flags.Transparent
// Keep: aligned with Quotes's `newMethod` doc
private[QuotesImpl] def validMethodFlags: Flags = Private | Protected | Override | Deferred | Final | Method | Implicit | Given | Local | AbsOverride | JavaStatic | Synthetic | Artifact // Flags that could be allowed: Synthetic | ExtensionMethod | Exported | Erased | Infix | Invisible
// Keep: aligned with Quotes's `newVal` doc
private[QuotesImpl] def validValFlags: Flags = Private | Protected | Override | Deferred | Final | Param | Implicit | Lazy | Mutable | Local | ParamAccessor | Module | Package | Case | CaseAccessor | Given | Enum | AbsOverride | JavaStatic | Synthetic | Artifact // Flags that could be added: Synthetic | Erased | Invisible
// Keep: aligned with Quotes's `newBind` doc
private[QuotesImpl] def validBindFlags: Flags = Case // Flags that could be allowed: Implicit | Given | Erased
end Flags
given FlagsMethods: FlagsMethods with
extension (self: Flags)
def is(that: Flags): Boolean = self.isAllOf(that)
def |(that: Flags): Flags = dotc.core.Flags.or(self, that) // TODO: Replace with dotc.core.Flags.|(self)(that) once extension names have stabilized
def &(that: Flags): Flags = dotc.core.Flags.and(self, that)// TODO: Replace with dotc.core.Flags.&(self)(that) once extension names have stabilized
def show: String = Extractors.showFlags(using QuotesImpl.this)(self)
end extension
end FlagsMethods
type Position = dotc.util.SourcePosition
object Position extends PositionModule:
def ofMacroExpansion: dotc.util.SourcePosition =
MacroExpansion.position.getOrElse(dotc.util.SourcePosition(ctx.source, dotc.util.Spans.NoSpan))
def apply(sourceFile: SourceFile, start: Int, end: Int): Position =
dotc.util.SourcePosition(sourceFile, dotc.util.Spans.Span(start, end))
end Position
given PositionMethods: PositionMethods with
extension (self: Position)
def start: Int = self.start
def end: Int = self.end
def sourceFile: SourceFile = self.source
def startLine: Int = self.startLine
def endLine: Int = self.endLine
def startColumn: Int = self.startColumn
def endColumn: Int = self.endColumn
def sourceCode: Option[String] =
val contents = self.source.content()
if contents.length < self.end then None
else Some(new String(contents, self.start, self.end - self.start))
end extension
end PositionMethods
type SourceFile = dotc.util.SourceFile
object SourceFile extends SourceFileModule {
def current: SourceFile =
val unit = ctx.compilationUnit
if unit eq NoCompilationUnit then
throw new java.lang.UnsupportedOperationException(
"`reflect.SourceFile.current` cannot be called within the TASTy ispector")
else unit.source
}
given SourceFileMethods: SourceFileMethods with
extension (self: SourceFile)
def jpath: java.nio.file.Path = self.file.jpath
def getJPath: Option[java.nio.file.Path] = Option(self.file.jpath)
def name: String = self.name
def path: String = self.path
def content: Option[String] =
// TODO detect when we do not have a source and return None
Some(new String(self.content()))
end extension
end SourceFileMethods
object report extends reportModule:
def error(msg: String): Unit =
dotc.report.error(msg, Position.ofMacroExpansion)
def error(msg: String, expr: Expr[Any]): Unit =
dotc.report.error(msg, asTerm(expr).pos)
def error(msg: String, pos: Position): Unit =
dotc.report.error(msg, pos)
def throwError(msg: String): Nothing =
errorAndAbort(msg)
def throwError(msg: String, expr: Expr[Any]): Nothing =
errorAndAbort(msg, expr)
def throwError(msg: String, pos: Position): Nothing =
errorAndAbort(msg, pos)
def errorAndAbort(msg: String): Nothing =
error(msg)
throw new scala.quoted.runtime.StopMacroExpansion
def errorAndAbort(msg: String, expr: Expr[Any]): Nothing =
error(msg, expr)
throw new scala.quoted.runtime.StopMacroExpansion
def errorAndAbort(msg: String, pos: Position): Nothing =
error(msg, pos)
throw new scala.quoted.runtime.StopMacroExpansion
def warning(msg: String): Unit =
dotc.report.warning(msg, Position.ofMacroExpansion)
def warning(msg: String, expr: Expr[Any]): Unit =
dotc.report.warning(msg, asTerm(expr).pos)
def warning(msg: String, pos: Position): Unit =
dotc.report.warning(msg, pos)
def info(msg: String): Unit =
dotc.report.echo(msg, Position.ofMacroExpansion)
def info(msg: String, expr: Expr[Any]): Unit =
dotc.report.echo(msg, asTerm(expr).pos)
def info(msg: String, pos: Position): Unit =
dotc.report.echo(msg, pos)
end report
private def optional[T <: dotc.ast.Trees.Tree[?]](tree: T): Option[tree.type] =
if tree.isEmpty then None else Some(tree)
private def withDefaultPos[T <: Tree](fn: Context ?=> T): T =
fn(using ctx.withSource(Position.ofMacroExpansion.source)).withSpan(Position.ofMacroExpansion.span)
/** Checks that all definitions in this tree have the expected owner.
* Nested definitions are ignored and assumed to be correct by construction.
*/
private def xCheckedMacroOwners(tree: Option[Tree], owner: Symbol): tree.type =
if xCheckMacro then
tree match
case Some(tree) =>
xCheckMacroOwners(tree, owner)
case _ =>
tree
/** Checks that all definitions in this tree have the expected owner.
* Nested definitions are ignored and assumed to be correct by construction.
*/
private def xCheckedMacroOwners(tree: Tree, owner: Symbol): tree.type =
if xCheckMacro then
xCheckMacroOwners(tree, owner)
tree
/** Checks that all definitions in this tree have the expected owner.
* Nested definitions are ignored and assumed to be correct by construction.
*/
private def xCheckMacroOwners(tree: Tree, owner: Symbol): Unit =
new tpd.TreeTraverser {
def traverse(t: Tree)(using Context): Unit =
t match
case t: tpd.DefTree =>
val defOwner = t.symbol.owner
assert(defOwner == owner, {
val ownerName = owner.fullName
val defOwnerName = defOwner.fullName
val duplicateSymbolHint =
if ownerName == defOwnerName then "These are two different symbols instances with the same name. The symbol should have been instantiated only once.\n"
else ""
s"""Tree had an unexpected owner for ${t.symbol}
|Expected: $owner (${owner.fullName})
|But was: $defOwner (${defOwner.fullName})
|$duplicateSymbolHint
|The code of the definition of ${t.symbol} is
|${Printer.TreeCode.show(t)}
|
|which was found in the code
|${Printer.TreeCode.show(tree)}
|
|which has the AST representation
|${Printer.TreeStructure.show(tree)}
|
|
|
|Tip: The owner of a tree can be changed using method `Tree.changeOwner`.
|Tip: The default owner of definitions created in quotes can be changed using method `Symbol.asQuotes`.
|""".stripMargin
})
case _ => traverseChildren(t)
}.traverse(tree)
/** Checks that all definitions in this block have the same owner.
* Nested definitions are ignored and assumed to be correct by construction.
*/
private def xCheckMacroBlockOwners(tree: Tree): tree.type =
if xCheckMacro then
val defs = new tpd.TreeAccumulator[List[Tree]] {
def apply(defs: List[Tree], tree: Tree)(using Context): List[Tree] =
tree match
case tree: tpd.DefTree => tree :: defs
case _ => foldOver(defs, tree)
}.apply(Nil, tree)
val defOwners = defs.groupBy(_.symbol.owner)
assert(defOwners.size <= 1,
s"""Block contains definition with different owners.
|Found definitions ${defOwners.size} distinct owners: ${defOwners.keys.mkString(", ")}
|
|Block: ${Printer.TreeCode.show(tree)}
|
|${defOwners.map((owner, trees) => s"Definitions owned by $owner: \n${trees.map(Printer.TreeCode.show).mkString("\n")}").mkString("\n\n")}
|""".stripMargin)
tree
private def xCheckMacroValidExprs(terms: List[Term]): terms.type =
if xCheckMacro then terms.foreach(xCheckMacroValidExpr)
terms
private def xCheckMacroValidExpr(termOpt: Option[Term]): termOpt.type =
if xCheckMacro then termOpt.foreach(xCheckMacroValidExpr)
termOpt
private def xCheckMacroValidExpr(term: Term): term.type =
xCheckMacroAssert(!term.tpe.widenDealias.isInstanceOf[dotc.core.Types.MethodicType],
"Reference to a method must be eta-expanded before it is used as an expression: " + term.show)
term
private inline def xCheckMacroAssert(inline cond: Boolean, inline msg: String): Unit =
if xCheckMacro && !cond then
xCheckMacroAssertFail(msg)
private def xCheckMacroAssertFail(msg: String): Unit =
val error = new AssertionError(msg)
if !yDebugMacro then
// start stack trace at the place where the user called the reflection method
error.setStackTrace(
error.getStackTrace
.dropWhile(_.getClassName().startsWith("scala.quoted.runtime.impl")))
throw error
object Printer extends PrinterModule:
lazy val TreeCode: Printer[Tree] = new Printer[Tree]:
def show(tree: Tree): String =
SourceCode.showTree(using QuotesImpl.this)(tree)(SyntaxHighlight.plain, fullNames = true)
lazy val TreeShortCode: Printer[Tree] = new Printer[Tree]:
def show(tree: Tree): String =
SourceCode.showTree(using QuotesImpl.this)(tree)(SyntaxHighlight.plain, fullNames = false)
lazy val TreeAnsiCode: Printer[Tree] = new Printer[Tree]:
def show(tree: Tree): String =
SourceCode.showTree(using QuotesImpl.this)(tree)(SyntaxHighlight.ANSI, fullNames = true)
lazy val TreeStructure: Printer[Tree] = new Printer[Tree]:
def show(tree: Tree): String =
Extractors.showTree(using QuotesImpl.this)(tree)
lazy val TypeReprCode: Printer[TypeRepr] = new Printer[TypeRepr]:
def show(tpe: TypeRepr): String =
SourceCode.showType(using QuotesImpl.this)(tpe)(SyntaxHighlight.plain, fullNames = true)
lazy val TypeReprShortCode: Printer[TypeRepr] = new Printer[TypeRepr]:
def show(tpe: TypeRepr): String =
SourceCode.showType(using QuotesImpl.this)(tpe)(SyntaxHighlight.plain, fullNames = false)
lazy val TypeReprAnsiCode: Printer[TypeRepr] = new Printer[TypeRepr]:
def show(tpe: TypeRepr): String =
SourceCode.showType(using QuotesImpl.this)(tpe)(SyntaxHighlight.ANSI, fullNames = true)
lazy val TypeReprStructure: Printer[TypeRepr] = new Printer[TypeRepr]:
def show(tpe: TypeRepr): String =
Extractors.showType(using QuotesImpl.this)(tpe)
lazy val ConstantCode: Printer[Constant] = new Printer[Constant]:
def show(const: Constant): String =
const.show(using ctx.withoutColors)
lazy val ConstantStructure: Printer[Constant] = new Printer[Constant]:
def show(const: Constant): String =
Extractors.showConstant(using QuotesImpl.this)(const)
end Printer
end reflect
def unpickleExpr[T](pickled: String | List[String], typeHole: (Int, Seq[Any]) => scala.quoted.Type[?], termHole: (Int, Seq[Any], scala.quoted.Quotes) => scala.quoted.Expr[?]): scala.quoted.Expr[T] =
val tree = PickledQuotes.unpickleTerm(pickled, PickledQuotes.TypeHole.V1(typeHole), PickledQuotes.ExprHole.V1(termHole))
new ExprImpl(tree, SpliceScope.getCurrent).asInstanceOf[scala.quoted.Expr[T]]
def unpickleExprV2[T](pickled: String | List[String], types: Seq[Type[?]], termHole: Null | ((Int, Seq[Type[?] | Expr[Any]], Quotes) => Expr[?])): scala.quoted.Expr[T] =
val tree = PickledQuotes.unpickleTerm(pickled, PickledQuotes.TypeHole.V2(types), PickledQuotes.ExprHole.V2(termHole))
new ExprImpl(tree, SpliceScope.getCurrent).asInstanceOf[scala.quoted.Expr[T]]
def unpickleType[T <: AnyKind](pickled: String | List[String], typeHole: (Int, Seq[Any]) => scala.quoted.Type[?], termHole: (Int, Seq[Any], scala.quoted.Quotes) => scala.quoted.Expr[?]): scala.quoted.Type[T] =
val tree = PickledQuotes.unpickleTypeTree(pickled, PickledQuotes.TypeHole.V1(typeHole))
new TypeImpl(tree, SpliceScope.getCurrent).asInstanceOf[scala.quoted.Type[T]]
def unpickleTypeV2[T <: AnyKind](pickled: String | List[String], types: Seq[Type[?]]): scala.quoted.Type[T] =
val tree = PickledQuotes.unpickleTypeTree(pickled, PickledQuotes.TypeHole.V2(types))
new TypeImpl(tree, SpliceScope.getCurrent).asInstanceOf[scala.quoted.Type[T]]
object ExprMatch extends ExprMatchModule:
def unapply[TypeBindings, Tup <: Tuple](scrutinee: scala.quoted.Expr[Any])(using pattern: scala.quoted.Expr[Any]): Option[Tup] =
val scrutineeTree = reflect.asTerm(scrutinee)
val patternTree = reflect.asTerm(pattern)
QuoteMatcher(yDebugMacro).treeMatch(scrutineeTree, patternTree).asInstanceOf[Option[Tup]]
end ExprMatch
object TypeMatch extends TypeMatchModule:
def unapply[TypeBindings, Tup <: Tuple](scrutinee: scala.quoted.Type[?])(using pattern: scala.quoted.Type[?]): Option[Tup] =
val scrutineeTree = reflect.TypeTree.of(using scrutinee)
val patternTree = reflect.TypeTree.of(using pattern)
QuoteMatcher(yDebugMacro).treeMatch(scrutineeTree, patternTree).asInstanceOf[Option[Tup]]
end TypeMatch
end QuotesImpl
© 2015 - 2025 Weber Informatics LLC | Privacy Policy