Skip to content

Commit 46fc22b

Browse files
authored
Add reflect.ValOrDefDef (#16974)
Closes #16960
2 parents 082dc6f + 3f17727 commit 46fc22b

File tree

5 files changed

+77
-5
lines changed

5 files changed

+77
-5
lines changed

compiler/src/scala/quoted/runtime/impl/QuotesImpl.scala

+15
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,21 @@ class QuotesImpl private (using val ctx: Context) extends Quotes, QuoteUnpickler
268268
end extension
269269
end ClassDefMethods
270270

271+
type ValOrDefDef = tpd.ValOrDefDef
272+
273+
object ValOrDefDefTypeTest extends TypeTest[Tree, ValOrDefDef]:
274+
def unapply(x: Tree): Option[ValOrDefDef & x.type] = x match
275+
case x: (tpd.ValOrDefDef & x.type) => Some(x)
276+
case _ => None
277+
end ValOrDefDefTypeTest
278+
279+
given ValOrDefDefMethods: ValOrDefDefMethods with
280+
extension (self: ValOrDefDef)
281+
def tpt: TypeTree = self.tpt
282+
def rhs: Option[Term] = optional(self.rhs)
283+
end extension
284+
end ValOrDefDefMethods
285+
271286
type DefDef = tpd.DefDef
272287

273288
object DefDefTypeTest extends TypeTest[Tree, DefDef]:

library/src/scala/quoted/Quotes.scala

+28-5
Original file line numberDiff line numberDiff line change
@@ -135,8 +135,8 @@ trait Quotes { self: runtime.QuoteUnpickler & runtime.QuoteMatching =>
135135
* | +- Export
136136
* | +- Definition --+- ClassDef
137137
* | | +- TypeDef
138-
* | | +- DefDef
139-
* | | +- ValDef
138+
* | | +- ValOrDefDef -+- DefDef
139+
* | | +- ValDef
140140
* | |
141141
* | +- Term --------+- Ref -+- Ident -+- Wildcard
142142
* | | +- Select
@@ -551,10 +551,33 @@ trait Quotes { self: runtime.QuoteUnpickler & runtime.QuoteMatching =>
551551
end extension
552552
end ClassDefMethods
553553

554+
// ValOrDefDef
555+
556+
/** Tree representing a value or method definition in the source code.
557+
* This includes `def`, `val`, `lazy val`, `var`, `object` and parameter definitions.
558+
*/
559+
type ValOrDefDef <: Definition
560+
561+
/** `TypeTest` that allows testing at runtime in a pattern match if a `Tree` is a `ValOrDefDef` */
562+
given ValOrDefDefTypeTest: TypeTest[Tree, ValOrDefDef]
563+
564+
/** Makes extension methods on `ValOrDefDef` available without any imports */
565+
given ValOrDefDefMethods: ValOrDefDefMethods
566+
567+
/** Extension methods of `ValOrDefDef` */
568+
trait ValOrDefDefMethods:
569+
extension (self: ValOrDefDef)
570+
/** The type tree of this `val` or `def` definition */
571+
def tpt: TypeTree
572+
/** The right-hand side of this `val` or `def` definition */
573+
def rhs: Option[Term]
574+
end extension
575+
end ValOrDefDefMethods
576+
554577
// DefDef
555578

556579
/** Tree representing a method definition in the source code */
557-
type DefDef <: Definition
580+
type DefDef <: ValOrDefDef
558581

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

631654
// ValDef
632655

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

636659
/** `TypeTest` that allows testing at runtime in a pattern match if a `Tree` is a `ValDef` */
637660
given ValDefTypeTest: TypeTest[Tree, ValDef]

project/MiMaFilters.scala

+4
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@ import com.typesafe.tools.mima.core._
33

44
object MiMaFilters {
55
val Library: Seq[ProblemFilter] = Seq(
6+
// New API in 3.4.X
7+
ProblemFilters.exclude[ReversedMissingMethodProblem]("scala.quoted.Quotes#reflectModule.ValOrDefDefTypeTest"),
8+
ProblemFilters.exclude[ReversedMissingMethodProblem]("scala.quoted.Quotes#reflectModule.ValOrDefDefMethods"),
9+
// New API in 3.4.X
610
)
711
val TastyCore: Seq[ProblemFilter] = Seq(
812
)

tests/pos-macros/i16960/Macro_1.scala

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import scala.quoted.*
2+
3+
inline def myMacro = ${ myMacroImpl }
4+
def myMacroImpl(using Quotes) =
5+
import quotes.reflect.*
6+
7+
val valSym = Symbol.newVal(Symbol.spliceOwner, "foo", TypeRepr.of[Int], Flags.EmptyFlags, Symbol.noSymbol)
8+
val vdef = ValDef(valSym, None)
9+
vdef match
10+
case _: ValDef =>
11+
assert(vdef.tpt.tpe =:= TypeRepr.of[Int])
12+
assert(vdef.rhs == None)
13+
vdef match
14+
case vdef: ValOrDefDef =>
15+
assert(vdef.tpt.tpe =:= TypeRepr.of[Int])
16+
assert(vdef.rhs == None)
17+
18+
val methSym = Symbol.newMethod(Symbol.spliceOwner, "bar", ByNameType(TypeRepr.of[Int]))
19+
val ddef = DefDef(methSym, _ => None)
20+
ddef match
21+
case _: DefDef =>
22+
assert(ddef.tpt.tpe =:= TypeRepr.of[Int])
23+
assert(ddef.rhs == None)
24+
ddef match
25+
case ddef: ValOrDefDef =>
26+
assert(ddef.tpt.tpe =:= TypeRepr.of[Int])
27+
assert(ddef.rhs == None)
28+
29+
'{}

tests/pos-macros/i16960/Test_2.scala

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
def test = myMacro

0 commit comments

Comments
 (0)