Skip to content

Commit

Permalink
Add reflect.ValOrDefDef (#16974)
Browse files Browse the repository at this point in the history
Closes #16960
  • Loading branch information
smarter authored Jul 31, 2023
2 parents 082dc6f + 3f17727 commit 46fc22b
Show file tree
Hide file tree
Showing 5 changed files with 77 additions and 5 deletions.
15 changes: 15 additions & 0 deletions compiler/src/scala/quoted/runtime/impl/QuotesImpl.scala
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,21 @@ class QuotesImpl private (using val ctx: Context) extends Quotes, QuoteUnpickler
end extension
end ClassDefMethods

type ValOrDefDef = tpd.ValOrDefDef

object ValOrDefDefTypeTest extends TypeTest[Tree, ValOrDefDef]:
def unapply(x: Tree): Option[ValOrDefDef & x.type] = x match
case x: (tpd.ValOrDefDef & x.type) => Some(x)
case _ => None
end ValOrDefDefTypeTest

given ValOrDefDefMethods: ValOrDefDefMethods with
extension (self: ValOrDefDef)
def tpt: TypeTree = self.tpt
def rhs: Option[Term] = optional(self.rhs)
end extension
end ValOrDefDefMethods

type DefDef = tpd.DefDef

object DefDefTypeTest extends TypeTest[Tree, DefDef]:
Expand Down
33 changes: 28 additions & 5 deletions library/src/scala/quoted/Quotes.scala
Original file line number Diff line number Diff line change
Expand Up @@ -135,8 +135,8 @@ trait Quotes { self: runtime.QuoteUnpickler & runtime.QuoteMatching =>
* | +- Export
* | +- Definition --+- ClassDef
* | | +- TypeDef
* | | +- DefDef
* | | +- ValDef
* | | +- ValOrDefDef -+- DefDef
* | | +- ValDef
* | |
* | +- Term --------+- Ref -+- Ident -+- Wildcard
* | | +- Select
Expand Down Expand Up @@ -551,10 +551,33 @@ trait Quotes { self: runtime.QuoteUnpickler & runtime.QuoteMatching =>
end extension
end ClassDefMethods

// ValOrDefDef

/** Tree representing a value or method definition in the source code.
* This includes `def`, `val`, `lazy val`, `var`, `object` and parameter definitions.
*/
type ValOrDefDef <: Definition

/** `TypeTest` that allows testing at runtime in a pattern match if a `Tree` is a `ValOrDefDef` */
given ValOrDefDefTypeTest: TypeTest[Tree, ValOrDefDef]

/** Makes extension methods on `ValOrDefDef` available without any imports */
given ValOrDefDefMethods: ValOrDefDefMethods

/** Extension methods of `ValOrDefDef` */
trait ValOrDefDefMethods:
extension (self: ValOrDefDef)
/** The type tree of this `val` or `def` definition */
def tpt: TypeTree
/** The right-hand side of this `val` or `def` definition */
def rhs: Option[Term]
end extension
end ValOrDefDefMethods

// DefDef

/** Tree representing a method definition in the source code */
type DefDef <: Definition
type DefDef <: ValOrDefDef

/** `TypeTest` that allows testing at runtime in a pattern match if a `Tree` is a `DefDef` */
given DefDefTypeTest: TypeTest[Tree, DefDef]
Expand Down Expand Up @@ -630,8 +653,8 @@ trait Quotes { self: runtime.QuoteUnpickler & runtime.QuoteMatching =>

// ValDef

/** Tree representing a value definition in the source code This includes `val`, `lazy val`, `var`, `object` and parameter definitions. */
type ValDef <: Definition
/** Tree representing a value definition in the source code. This includes `val`, `lazy val`, `var`, `object` and parameter definitions. */
type ValDef <: ValOrDefDef

/** `TypeTest` that allows testing at runtime in a pattern match if a `Tree` is a `ValDef` */
given ValDefTypeTest: TypeTest[Tree, ValDef]
Expand Down
4 changes: 4 additions & 0 deletions project/MiMaFilters.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@ import com.typesafe.tools.mima.core._

object MiMaFilters {
val Library: Seq[ProblemFilter] = Seq(
// New API in 3.4.X
ProblemFilters.exclude[ReversedMissingMethodProblem]("scala.quoted.Quotes#reflectModule.ValOrDefDefTypeTest"),
ProblemFilters.exclude[ReversedMissingMethodProblem]("scala.quoted.Quotes#reflectModule.ValOrDefDefMethods"),
// New API in 3.4.X
)
val TastyCore: Seq[ProblemFilter] = Seq(
)
Expand Down
29 changes: 29 additions & 0 deletions tests/pos-macros/i16960/Macro_1.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import scala.quoted.*

inline def myMacro = ${ myMacroImpl }
def myMacroImpl(using Quotes) =
import quotes.reflect.*

val valSym = Symbol.newVal(Symbol.spliceOwner, "foo", TypeRepr.of[Int], Flags.EmptyFlags, Symbol.noSymbol)
val vdef = ValDef(valSym, None)
vdef match
case _: ValDef =>
assert(vdef.tpt.tpe =:= TypeRepr.of[Int])
assert(vdef.rhs == None)
vdef match
case vdef: ValOrDefDef =>
assert(vdef.tpt.tpe =:= TypeRepr.of[Int])
assert(vdef.rhs == None)

val methSym = Symbol.newMethod(Symbol.spliceOwner, "bar", ByNameType(TypeRepr.of[Int]))
val ddef = DefDef(methSym, _ => None)
ddef match
case _: DefDef =>
assert(ddef.tpt.tpe =:= TypeRepr.of[Int])
assert(ddef.rhs == None)
ddef match
case ddef: ValOrDefDef =>
assert(ddef.tpt.tpe =:= TypeRepr.of[Int])
assert(ddef.rhs == None)

'{}
1 change: 1 addition & 0 deletions tests/pos-macros/i16960/Test_2.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
def test = myMacro

0 comments on commit 46fc22b

Please sign in to comment.