@@ -467,9 +467,33 @@ trait Quotes { self: runtime.QuoteUnpickler & runtime.QuoteMatching =>
467
467
* otherwise the can be `Term` containing the `New` applied to the parameters of the extended class.
468
468
* @param body List of members of the class. The members must align with the members of `cls`.
469
469
*/
470
+ // TODO add selfOpt: Option[ValDef]?
470
471
@ experimental def apply (cls : Symbol , parents : List [Tree /* Term | TypeTree */ ], body : List [Statement ]): ClassDef
471
472
def copy (original : Tree )(name : String , constr : DefDef , parents : List [Tree /* Term | TypeTree */ ], selfOpt : Option [ValDef ], body : List [Statement ]): ClassDef
472
473
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 (equivalent to an `object` declaration in source code).
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 (created using `Symbol.newModule`)
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 )
473
497
}
474
498
475
499
/** Makes extension methods on `ClassDef` available without any imports */
@@ -3638,8 +3662,67 @@ trait Quotes { self: runtime.QuoteUnpickler & runtime.QuoteMatching =>
3638
3662
* @note As a macro can only splice code into the point at which it is expanded, all generated symbols must be
3639
3663
* direct or indirect children of the reflection context's owner.
3640
3664
*/
3665
+ // TODO: add flags and privateWithin
3641
3666
@ experimental def newClass (parent : Symbol , name : String , parents : List [TypeRepr ], decls : Symbol => List [Symbol ], selfType : Option [TypeRepr ]): Symbol
3642
3667
3668
+ /** Generates a new module symbol with an associated module class symbol,
3669
+ * this is equivalent to an `object` declaration in source code.
3670
+ * This method returns the module symbol. The module class can be accessed calling `moduleClass` on this symbol.
3671
+ *
3672
+ * Example usage:
3673
+ * ```scala
3674
+ * //{
3675
+ * given Quotes = ???
3676
+ * import quotes.reflect._
3677
+ * //}
3678
+ * val moduleName: String = Symbol.freshName("MyModule")
3679
+ * val parents = List(TypeTree.of[Object])
3680
+ * def decls(cls: Symbol): List[Symbol] =
3681
+ * List(Symbol.newMethod(cls, "run", MethodType(Nil)(_ => Nil, _ => TypeRepr.of[Unit]), Flags.EmptyFlags, Symbol.noSymbol))
3682
+ *
3683
+ * val mod = Symbol.newModule(Symbol.spliceOwner, moduleName, Flags.EmptyFlags, Flags.EmptyFlags, parents.map(_.tpe), decls, Symbol.noSymbol)
3684
+ * val cls = mod.moduleClass
3685
+ * val runSym = cls.declaredMethod("run").head
3686
+ *
3687
+ * val runDef = DefDef(runSym, _ => Some('{ println("run") }.asTerm))
3688
+ * val modDef = ClassDef.module(mod, parents, body = List(runDef))
3689
+ *
3690
+ * val callRun = Apply(Select(Ref(mod), runSym), Nil)
3691
+ *
3692
+ * Block(modDef.toList, callRun)
3693
+ * ```
3694
+ * constructs the equivalent to
3695
+ * ```scala
3696
+ * //{
3697
+ * given Quotes = ???
3698
+ * import quotes.reflect._
3699
+ * //}
3700
+ * '{
3701
+ * object MyModule$macro$1 extends Object:
3702
+ * def run(): Unit = println("run")
3703
+ * MyModule$macro$1.run()
3704
+ * }
3705
+ * ```
3706
+ *
3707
+ * @param parent The owner of the class
3708
+ * @param name The name of the class
3709
+ * @param modFlags extra flags with which the module symbol should be constructed
3710
+ * @param clsFlags extra flags with which the module class symbol should be constructed
3711
+ * @param parents The parent classes of the class. The first parent must not be a trait.
3712
+ * @param decls A function that takes the symbol of the module class as input and return the symbols of its declared members
3713
+ * @param privateWithin the symbol within which this new method symbol should be private. May be noSymbol.
3714
+ *
3715
+ * This symbol starts without an accompanying definition.
3716
+ * It is the meta-programmer's responsibility to provide exactly one corresponding definition by passing
3717
+ * this symbol to `ClassDef.module`.
3718
+ *
3719
+ * @note As a macro can only splice code into the point at which it is expanded, all generated symbols must be
3720
+ * direct or indirect children of the reflection context's owner.
3721
+ *
3722
+ * @syntax markdown
3723
+ */
3724
+ @ experimental def newModule (owner : Symbol , name : String , modFlags : Flags , clsFlags : Flags , parents : List [TypeRepr ], decls : Symbol => List [Symbol ], privateWithin : Symbol ): Symbol
3725
+
3643
3726
/** Generates a new method symbol with the given parent, name and type.
3644
3727
*
3645
3728
* To define a member method of a class, use the `newMethod` within the `decls` function of `newClass`.
@@ -4217,7 +4300,7 @@ trait Quotes { self: runtime.QuoteUnpickler & runtime.QuoteMatching =>
4217
4300
// FLAGS //
4218
4301
// /////////////
4219
4302
4220
- /** FlagSet of a Symbol */
4303
+ /** Flags of a Symbol */
4221
4304
type Flags
4222
4305
4223
4306
/** Module object of `type Flags` */
0 commit comments