Skip to content

Commit d18ec54

Browse files
committed
Add missing apply constructors for Refined And TypeProjection TypeTrees
1 parent 5a2cff6 commit d18ec54

File tree

7 files changed

+77
-0
lines changed

7 files changed

+77
-0
lines changed

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1247,6 +1247,8 @@ class QuotesImpl private (using val ctx: Context) extends Quotes, QuoteUnpickler
12471247
end TypeProjectionTypeTest
12481248

12491249
object TypeProjection extends TypeProjectionModule:
1250+
def apply(qualifier: TypeTree, name: String): TypeProjection =
1251+
withDefaultPos(tpd.Select(qualifier, name.toTypeName))
12501252
def copy(original: Tree)(qualifier: TypeTree, name: String): TypeProjection =
12511253
tpd.cpy.Select(original)(qualifier, name.toTypeName)
12521254
def unapply(x: TypeProjection): (TypeTree, String) =
@@ -1292,6 +1294,9 @@ class QuotesImpl private (using val ctx: Context) extends Quotes, QuoteUnpickler
12921294
end RefinedTypeTest
12931295

12941296
object Refined extends RefinedModule:
1297+
def apply(tpt: TypeTree, refinements: List[Definition], refineCls: Symbol): Refined = // Symbol of the class being refined, according to which the refinements are typed
1298+
assert(refineCls.isClass, "refineCls must be a class/trait/object")
1299+
withDefaultPos(tpd.RefinedTypeTree(tpt, refinements, refineCls.asClass).asInstanceOf[tpd.RefinedTypeTree])
12951300
def copy(original: Tree)(tpt: TypeTree, refinements: List[Definition]): Refined =
12961301
tpd.cpy.RefinedTypeTree(original)(tpt, refinements)
12971302
def unapply(x: Refined): (TypeTree, List[Definition]) =

library/src/scala/quoted/Quotes.scala

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1974,6 +1974,7 @@ trait Quotes { self: runtime.QuoteUnpickler & runtime.QuoteMatching =>
19741974

19751975
/** Methods of the module object `val TypeProjection` */
19761976
trait TypeProjectionModule { this: TypeProjection.type =>
1977+
def apply(qualifier: TypeTree, name: String): TypeProjection
19771978
def copy(original: Tree)(qualifier: TypeTree, name: String): TypeProjection
19781979
def unapply(x: TypeProjection): (TypeTree, String)
19791980
}
@@ -2026,6 +2027,13 @@ trait Quotes { self: runtime.QuoteUnpickler & runtime.QuoteMatching =>
20262027

20272028
/** Methods of the module object `val Refined` */
20282029
trait RefinedModule { this: Refined.type =>
2030+
/** Creates and types a Refined AST node.
2031+
* @param tpt - parent type being refined
2032+
* @param refinements - List of definitions represesenting refinements
2033+
* @param refineCls - symbol of the class of which the refinement definitions originally come from
2034+
* @return
2035+
*/
2036+
def apply(tpt: TypeTree, refinements: List[Definition], refineCls: Symbol): Refined
20292037
def copy(original: Tree)(tpt: TypeTree, refinements: List[Definition]): Refined
20302038
def unapply(x: Refined): (TypeTree, List[Definition])
20312039
}

project/MiMaFilters.scala

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,8 @@ object MiMaFilters {
141141
ProblemFilters.exclude[ReversedMissingMethodProblem]("scala.quoted.Quotes#reflectModule#SymbolModule.newClass"),
142142
ProblemFilters.exclude[ReversedMissingMethodProblem]("scala.quoted.Quotes#reflectModule#SymbolModule.newModule"),
143143
ProblemFilters.exclude[ReversedMissingMethodProblem]("scala.quoted.Quotes#reflectModule#TermMethods.ensureApplied"),
144+
ProblemFilters.exclude[ReversedMissingMethodProblem]("scala.quoted.Quotes#reflectModule#RefinedModule.apply"),
145+
ProblemFilters.exclude[ReversedMissingMethodProblem]("scala.quoted.Quotes#reflectModule#TypeProjectionModule.apply"),
144146

145147
// Changes to lazy vals (added static constructors)
146148
ProblemFilters.exclude[DirectMissingMethodProblem]("scala.Tuple.<clinit>"),
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import scala.quoted._
2+
class Test {type test = Int }
3+
object Macro:
4+
inline def inlineCall(): Any = ${impl}
5+
transparent inline def transparentInlineCall(): Any = ${impl}
6+
7+
/* Returns:
8+
* val value: Test#test = 0 : Test#test
9+
* value: Test#test
10+
*/
11+
def impl(using Quotes): Expr[Any] =
12+
import quotes.reflect._
13+
val typeTree = TypeProjection(TypeTree.of[Test], "test")
14+
val typeRepr = TypeRepr.of[Test#test]
15+
val sym = Symbol.newVal(Symbol.spliceOwner, "value", typeRepr, Flags.EmptyFlags, Symbol.noSymbol)
16+
Block(
17+
List(ValDef(sym, Some(Typed(Literal(IntConstant(0)), typeTree)))),
18+
Typed(Ref(sym), typeTree)
19+
).asExpr
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
import scala.quoted._
2+
def test() =
3+
Macro.transparentInlineCall()
4+
Macro.inlineCall()
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
//> using options -experimental
2+
import scala.quoted._
3+
class Foo { type test1; val test2: List[Any] = List() }
4+
object Macro:
5+
inline def inlineCall(): Any = ${impl}
6+
transparent inline def transparentInlineCall(): Any = ${impl}
7+
8+
def impl(using Quotes): Expr[Any] =
9+
import quotes.reflect._
10+
val tpt = TypeTree.of[Foo]
11+
12+
val typeDefSym = Symbol.newTypeAlias(Symbol.spliceOwner, "test1", Flags.EmptyFlags, TypeRepr.of[Int], Symbol.noSymbol)
13+
val valDefSym = Symbol.newVal(Symbol.spliceOwner, "test2", TypeRepr.of[List[Int]], Flags.EmptyFlags, Symbol.noSymbol)
14+
15+
val defs = List(
16+
TypeDef(typeDefSym),
17+
ValDef(valDefSym, None)
18+
)
19+
val typeTree = Refined(tpt, defs, TypeRepr.of[Foo].typeSymbol)
20+
21+
// A little redundant, but we only want to see if Refined.apply() works,
22+
// so we only replace the type with one we just constructed
23+
val body = '{
24+
new Foo { type test1 = Int; override val test2: List[Int] = List(0) }
25+
}
26+
val blockWithNewTypeTree = body.asTerm match
27+
case Inlined(_, _, Block(cDef : ClassDef, Typed(invocation, _))) =>
28+
Block(cDef, Typed(invocation, typeTree))
29+
30+
blockWithNewTypeTree.asExpr
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
//> using options -experimental
2+
3+
import scala.quoted._
4+
def testInt(i: Int) = ()
5+
@main def Test(): Unit =
6+
val withType = Macro.transparentInlineCall()
7+
summon[withType.test1 <:< Int]
8+
withType.test2.map(testInt)
9+
Macro.inlineCall()

0 commit comments

Comments
 (0)