Skip to content

Commit 47881da

Browse files
authored
Add apply methods to import selectors in Quotes #21225 (#22457)
For now added as experimental. Fixes #21225
2 parents bb2aadb + 3cd45e9 commit 47881da

File tree

6 files changed

+68
-0
lines changed

6 files changed

+68
-0
lines changed

Diff for: compiler/src/scala/quoted/runtime/impl/QuotesImpl.scala

+11
Original file line numberDiff line numberDiff line change
@@ -1694,6 +1694,8 @@ class QuotesImpl private (using val ctx: Context) extends Quotes, QuoteUnpickler
16941694
end SimpleSelectorTypeTest
16951695

16961696
object SimpleSelector extends SimpleSelectorModule:
1697+
def apply(name: String): SimpleSelector =
1698+
withDefaultPos(untpd.ImportSelector(untpd.Ident(name.toTermName)))
16971699
def unapply(x: SimpleSelector): Some[String] = Some(x.name.toString)
16981700
end SimpleSelector
16991701

@@ -1713,6 +1715,8 @@ class QuotesImpl private (using val ctx: Context) extends Quotes, QuoteUnpickler
17131715
end RenameSelectorTypeTest
17141716

17151717
object RenameSelector extends RenameSelectorModule:
1718+
def apply(fromName: String, toName: String): RenameSelector =
1719+
withDefaultPos(untpd.ImportSelector(untpd.Ident(fromName.toTermName), untpd.Ident(toName.toTermName)))
17161720
def unapply(x: RenameSelector): (String, String) = (x.fromName, x.toName)
17171721
end RenameSelector
17181722

@@ -1738,6 +1742,8 @@ class QuotesImpl private (using val ctx: Context) extends Quotes, QuoteUnpickler
17381742
end OmitSelectorTypeTest
17391743

17401744
object OmitSelector extends OmitSelectorModule:
1745+
def apply(name: String): OmitSelector =
1746+
withDefaultPos(untpd.ImportSelector(untpd.Ident(name.toTermName), untpd.Ident(nme.WILDCARD)))
17411747
def unapply(x: OmitSelector): Some[String] = Some(x.imported.name.toString)
17421748
end OmitSelector
17431749

@@ -1758,6 +1764,11 @@ class QuotesImpl private (using val ctx: Context) extends Quotes, QuoteUnpickler
17581764
end GivenSelectorTypeTest
17591765

17601766
object GivenSelector extends GivenSelectorModule:
1767+
def apply(bound: Option[TypeTree]): GivenSelector =
1768+
withDefaultPos(untpd.ImportSelector(
1769+
untpd.Ident(nme.EMPTY),
1770+
bound = bound.map(tpt => untpd.TypedSplice(tpt)).getOrElse(EmptyTree)
1771+
))
17611772
def unapply(x: GivenSelector): Some[Option[TypeTree]] =
17621773
Some(GivenSelectorMethods.bound(x))
17631774
end GivenSelector

Diff for: library/src/scala/quoted/Quotes.scala

+4
Original file line numberDiff line numberDiff line change
@@ -2544,6 +2544,7 @@ trait Quotes { self: runtime.QuoteUnpickler & runtime.QuoteMatching =>
25442544

25452545
/** Methods of the module object `val SimpleSelector` */
25462546
trait SimpleSelectorModule { this: SimpleSelector.type =>
2547+
@experimental def apply(name: String): SimpleSelector
25472548
def unapply(x: SimpleSelector): Some[String]
25482549
}
25492550

@@ -2569,6 +2570,7 @@ trait Quotes { self: runtime.QuoteUnpickler & runtime.QuoteMatching =>
25692570

25702571
/** Methods of the module object `val RenameSelector` */
25712572
trait RenameSelectorModule { this: RenameSelector.type =>
2573+
@experimental def apply(fromName: String, toName: String): RenameSelector
25722574
def unapply(x: RenameSelector): (String, String)
25732575
}
25742576

@@ -2596,6 +2598,7 @@ trait Quotes { self: runtime.QuoteUnpickler & runtime.QuoteMatching =>
25962598

25972599
/** Methods of the module object `val OmitSelector` */
25982600
trait OmitSelectorModule { this: OmitSelector.type =>
2601+
@experimental def apply(name: String): OmitSelector
25992602
def unapply(x: OmitSelector): Some[String]
26002603
}
26012604

@@ -2620,6 +2623,7 @@ trait Quotes { self: runtime.QuoteUnpickler & runtime.QuoteMatching =>
26202623

26212624
/** Methods of the module object `val GivenSelector` */
26222625
trait GivenSelectorModule { this: GivenSelector.type =>
2626+
@experimental def apply(bound: Option[TypeTree]): GivenSelector
26232627
def unapply(x: GivenSelector): Some[Option[TypeTree]]
26242628
}
26252629

Diff for: tests/run-macros/i21225.check

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
bar codec
2+
foo codec

Diff for: tests/run-macros/i21225/Macro_1.scala

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
//> using options -experimental
2+
3+
import scala.quoted.*
4+
5+
trait Codec[-T] { def print(): Unit }
6+
object Codec {
7+
inline def derivedWithDeps[T](deps: Any): Codec[T] = ${derivedWithDepsImpl[T]('deps)}
8+
9+
private def derivedWithDepsImpl[T](deps: Expr[Any])(using q: Quotes)(using Type[T]): Expr[Codec[T]] = {
10+
import q.reflect.*
11+
12+
val givenSelector: Selector = GivenSelector(None)
13+
val theImport = Import(deps.asTerm, List(givenSelector))
14+
Block(List(theImport), '{scala.compiletime.summonInline[Codec[T]]}.asTerm).asExprOf[Codec[T]]
15+
/* import deps.given
16+
* summonInline[Codec[T]]
17+
*/
18+
}
19+
20+
inline def derivedWithDepsWithNamedOmitted[T](deps: Any): Codec[T] = ${derivedWithDepsWithNamedOmittedImpl[T]('deps)}
21+
22+
private def derivedWithDepsWithNamedOmittedImpl[T](deps: Expr[Any])(using q: Quotes)(using Type[T]): Expr[Codec[T]] = {
23+
import q.reflect.*
24+
25+
val givenSelector: Selector = GivenSelector(None)
26+
val omitSelector: Selector = OmitSelector("named")
27+
val theImport = Import(deps.asTerm, List(givenSelector, omitSelector))
28+
Block(List(theImport), '{scala.compiletime.summonInline[Codec[T]]}.asTerm).asExprOf[Codec[T]]
29+
/* import deps.{given, named => _}
30+
* summonInline[Codec[T]]
31+
*/
32+
}
33+
}

Diff for: tests/run-macros/i21225/Test_2.scala

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
//> using options -experimental
2+
3+
import scala.quoted.*
4+
5+
sealed trait Foo
6+
class Bar extends Foo
7+
object CustomCodecs {
8+
given named: Codec[Bar] = new Codec[Bar] { def print(): Unit = println("bar codec")}
9+
given Codec[Foo] = new Codec[Foo] { def print(): Unit = println("foo codec") }
10+
}
11+
12+
@main def Test =
13+
Codec.derivedWithDeps[Bar](CustomCodecs).print()
14+
Codec.derivedWithDepsWithNamedOmitted[Bar](CustomCodecs).print()

Diff for: tests/run-tasty-inspector/stdlibExperimentalDefinitions.scala

+4
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,10 @@ val experimentalDefinitionInLibrary = Set(
7373
"scala.quoted.Quotes.reflectModule.MethodTypeMethods.hasErasedParams",
7474
"scala.quoted.Quotes.reflectModule.TermParamClauseMethods.erasedArgs",
7575
"scala.quoted.Quotes.reflectModule.TermParamClauseMethods.hasErasedArgs",
76+
"scala.quoted.Quotes.reflectModule.GivenSelectorModule.apply",
77+
"scala.quoted.Quotes.reflectModule.OmitSelectorModule.apply",
78+
"scala.quoted.Quotes.reflectModule.RenameSelectorModule.apply",
79+
"scala.quoted.Quotes.reflectModule.SimpleSelectorModule.apply",
7680

7781
// New feature: fromNullable for explicit nulls
7882
"scala.Predef$.fromNullable",

0 commit comments

Comments
 (0)