From aa2b565f297bd6d005bc71771c7e8bc3514b76fa Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Mon, 30 Oct 2023 11:22:58 +0100 Subject: [PATCH] Add documentation on Repeated and RepeatedParamClass Close #18784 --- library/src/scala/quoted/Quotes.scala | 31 ++++++++++++++++++++++++++- tests/pos/i18784/Macro_1.scala | 20 +++++++++++++++++ tests/pos/i18784/Test_2.scala | 2 ++ 3 files changed, 52 insertions(+), 1 deletion(-) create mode 100644 tests/pos/i18784/Macro_1.scala create mode 100644 tests/pos/i18784/Test_2.scala diff --git a/library/src/scala/quoted/Quotes.scala b/library/src/scala/quoted/Quotes.scala index 055c560ad64a..03f955645638 100644 --- a/library/src/scala/quoted/Quotes.scala +++ b/library/src/scala/quoted/Quotes.scala @@ -1622,7 +1622,30 @@ trait Quotes { self: runtime.QuoteUnpickler & runtime.QuoteMatching => end extension end ReturnMethods - /** Tree representing a variable argument list in the source code */ + /** Tree representing a variable argument list in the source code. + * + * This tree is used to encode varargs terms. The Repeated encapsulates + * the sequence of the elements but needs to be wrapped in a + * `scala.[T]` (see `defn.RepeatedParamClass`). For example the + * arguments `1, 2` of `List.apply(1, 2)` can be represented as follows: + * + * + * ```scala + * //{ + * import scala.quoted._ + * def inQuotes(using Quotes) = { + * val q: Quotes = summon[Quotes] + * import q.reflect._ + * //} + * val intArgs = List(Literal(Constant(1)), Literal(Constant(2))) + * Typed( + * Repeated(intArgs, TypeTree.of[Int]), + * Inferred(defn.RepeatedParamClass.typeRef.appliedTo(TypeRepr.of[Int])) + * //{ + * } + * //} + * ``` + */ type Repeated <: Term /** `TypeTest` that allows testing at runtime in a pattern match if a `Tree` is a `Repeated` */ @@ -1633,8 +1656,11 @@ trait Quotes { self: runtime.QuoteUnpickler & runtime.QuoteMatching => /** Methods of the module object `val Repeated` */ trait RepeatedModule { this: Repeated.type => + /** Create a literal sequence of elements */ def apply(elems: List[Term], tpt: TypeTree): Repeated + /** Copy a literal sequence of elements */ def copy(original: Tree)(elems: List[Term], tpt: TypeTree): Repeated + /** Matches a literal sequence of elements */ def unapply(x: Repeated): (List[Term], TypeTree) } @@ -4314,6 +4340,9 @@ trait Quotes { self: runtime.QuoteUnpickler & runtime.QuoteMatching => /** A dummy class symbol that is used to indicate repeated parameters * compiled by the Scala compiler. + * + * Used to represent the type `scala.[T]` which is + * a kind of sequence type of `T`s. */ def RepeatedParamClass: Symbol diff --git a/tests/pos/i18784/Macro_1.scala b/tests/pos/i18784/Macro_1.scala new file mode 100644 index 000000000000..2eb93205d5ac --- /dev/null +++ b/tests/pos/i18784/Macro_1.scala @@ -0,0 +1,20 @@ +import scala.quoted.* + +object Macro { + inline def repeated = ${Macro.repeatedImpl} + def repeatedImpl(using Quotes):Expr[List[Int]] = { + import quotes.reflect.* + val args = List(Expr(1), Expr(2)) + val listObjectTerm = '{ List }.asTerm + Apply( + TypeApply( + Select.unique(listObjectTerm, "apply"), + List(TypeTree.of[Int]) + ), + List( + Typed( + Repeated(args.map(_.asTerm), TypeTree.of[Int]), + Inferred(defn.RepeatedParamClass.typeRef.appliedTo(TypeRepr.of[Int])))) + ).asExprOf[List[Int]] + } +} \ No newline at end of file diff --git a/tests/pos/i18784/Test_2.scala b/tests/pos/i18784/Test_2.scala new file mode 100644 index 000000000000..a5fb441b4137 --- /dev/null +++ b/tests/pos/i18784/Test_2.scala @@ -0,0 +1,2 @@ +def Test: Unit = + Macro.repeated