Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add reflect.ValOrDefDef #16974

Merged
merged 1 commit into from
Jul 31, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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