Skip to content

Commit 2d3c60f

Browse files
committed
Add reflect ClassDef.module
1 parent 9f4042a commit 2d3c60f

File tree

5 files changed

+38
-18
lines changed

5 files changed

+38
-18
lines changed

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,14 @@ class QuotesImpl private (using val ctx: Context) extends Quotes, QuoteUnpickler
243243
def unapply(cdef: ClassDef): (String, DefDef, List[Tree /* Term | TypeTree */], Option[ValDef], List[Statement]) =
244244
val rhs = cdef.rhs.asInstanceOf[tpd.Template]
245245
(cdef.name.toString, cdef.constructor, cdef.parents, cdef.self, rhs.body)
246+
247+
def module(module: Symbol, parents: List[Tree /* Term | TypeTree */], body: List[Statement]): (ValDef, ClassDef) = {
248+
val cls = module.moduleClass
249+
val clsDef = ClassDef(cls, parents, body)
250+
val newCls = Apply(Select(New(TypeIdent(cls)), cls.primaryConstructor), Nil)
251+
val modVal = ValDef(module, Some(newCls))
252+
(modVal, clsDef)
253+
}
246254
end ClassDef
247255

248256
given ClassDefMethods: ClassDefMethods with

library/src/scala/quoted/Quotes.scala

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -467,9 +467,33 @@ trait Quotes { self: runtime.QuoteUnpickler & runtime.QuoteMatching =>
467467
* otherwise the can be `Term` containing the `New` applied to the parameters of the extended class.
468468
* @param body List of members of the class. The members must align with the members of `cls`.
469469
*/
470+
// TODO add selfOpt: Option[ValDef]?
470471
@experimental def apply(cls: Symbol, parents: List[Tree /* Term | TypeTree */], body: List[Statement]): ClassDef
471472
def copy(original: Tree)(name: String, constr: DefDef, parents: List[Tree /* Term | TypeTree */], selfOpt: Option[ValDef], body: List[Statement]): ClassDef
472473
def unapply(cdef: ClassDef): (String, DefDef, List[Tree /* Term | TypeTree */], Option[ValDef], List[Statement])
474+
475+
476+
/** Create the ValDef and ClassDef of a module.
477+
*
478+
* Equivalent to
479+
* ```
480+
* def module(module: Symbol, parents: List[Tree], body: List[Statement]): (ValDef, ClassDef) =
481+
* val modCls = module.moduleClass
482+
* val modClassDef = ClassDef(modCls, parents, body)
483+
* val modValDef = ValDef(module, Some(Apply(Select(New(TypeIdent(modCls)), cls.primaryConstructor), Nil)))
484+
* List(modValDef, modClassDef)
485+
* ```
486+
*
487+
* @param module the module symbol (of the module lazy val)
488+
* @param parents parents of the module class
489+
* @param body body of the module class
490+
* @return The module lazy val definition and module class definition.
491+
* These should be added one after the other (in that order) in the body of a class or statements of a block.
492+
*
493+
* @syntax markdown
494+
*/
495+
// TODO add selfOpt: Option[ValDef]?
496+
@experimental def module(module: Symbol, parents: List[Tree /* Term | TypeTree */], body: List[Statement]): (ValDef, ClassDef)
473497
}
474498

475499
/** Makes extension methods on `ClassDef` available without any imports */
@@ -3660,14 +3684,11 @@ trait Quotes { self: runtime.QuoteUnpickler & runtime.QuoteMatching =>
36603684
* val runSym = cls.declaredMethod("run").head
36613685
*
36623686
* val runDef = DefDef(runSym, _ => Some('{ println("run") }.asTerm))
3663-
* val clsDef = ClassDef(cls, parents, body = List(runDef))
3664-
* val newCls = Apply(Select(New(TypeIdent(cls)), cls.primaryConstructor), Nil)
3665-
* val modVal = ValDef(mod, Some(newCls))
3666-
* val modDef = List(modVal, clsDef)
3687+
* val modDef = ClassDef.module(mod, parents, body = List(runDef))
36673688
*
36683689
* val callRun = Apply(Select(Ref(mod), runSym), Nil)
36693690
*
3670-
* Block(modDef, callRun)
3691+
* Block(modDef.toList, callRun)
36713692
* ```
36723693
* constructs the equivalent to
36733694
* ```scala

tests/run-macros/annot-add-global-object/Macro_1.scala

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,10 @@ class addClass extends MacroAnnotation:
1919

2020
val runDef = DefDef(runSym, _ => Some(rhs))
2121

22-
val clsDef = ClassDef(cls, parents, body = List(runDef))
23-
24-
val newCls = Apply(Select(New(TypeIdent(cls)), cls.primaryConstructor), Nil)
25-
val modVal = ValDef(mod, Some(newCls))
22+
val modDef = ClassDef.module(mod, parents, body = List(runDef))
2623

2724
val newDef = DefDef.copy(tree)(name, List(TermParamClause(Nil)), tpt, Some(Apply(Select(Ref(mod), runSym), Nil)))
28-
List(modVal, clsDef, newDef)
25+
modDef.toList ::: newDef :: Nil
2926
case _ =>
3027
report.error("Annotation only supports `def` with one argument")
3128
List(tree)

tests/run-macros/annot-add-local-object/Macro_1.scala

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,7 @@ class addClass extends MacroAnnotation:
1919

2020
val runDef = DefDef(runSym, _ => Some(rhs))
2121

22-
val clsDef = ClassDef(cls, parents, body = List(runDef))
23-
24-
val newCls = Apply(Select(New(TypeIdent(cls)), cls.primaryConstructor), Nil)
25-
val modVal = ValDef(mod, Some(newCls))
22+
val (modVal, clsDef) = ClassDef.module(mod, parents, body = List(runDef))
2623

2724
val newDef = DefDef.copy(tree)(name, List(TermParamClause(Nil)), tpt, Some(Apply(Select(Ref(mod), runSym), Nil)))
2825
List(modVal, clsDef, newDef)

tests/run-macros/annot-add-nested-object/Macro_1.scala

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,7 @@ class addClass extends MacroAnnotation:
1919

2020
val runDef = DefDef(runSym, _ => Some(rhs))
2121

22-
val clsDef = ClassDef(cls, parents, body = List(runDef))
23-
24-
val newCls = Apply(Select(New(TypeIdent(cls)), cls.primaryConstructor), Nil)
25-
val modVal = ValDef(mod, Some(newCls))
22+
val (modVal, clsDef) = ClassDef.module(mod, parents, body = List(runDef))
2623

2724
val newDef = DefDef.copy(tree)(name, List(TermParamClause(Nil)), tpt, Some(Apply(Select(Ref(mod), runSym), Nil)))
2825
List(modVal, clsDef, newDef)

0 commit comments

Comments
 (0)