@@ -4,25 +4,41 @@ package annotation
4
4
5
5
import scala .quoted ._
6
6
7
- /** Base trait for macro annotation that will transform a definition */
7
+ /** Base trait for macro annotation implementation.
8
+ * Macro annotations can transform definitions and add new definitions.
9
+ *
10
+ * See: `MacroAnnotation.transform`
11
+ *
12
+ * @syntax markdown
13
+ */
8
14
@ experimental
9
15
trait MacroAnnotation extends StaticAnnotation :
10
16
11
- /** Transform the `tree` definition and add other definitions
17
+ /** Transform the `tree` definition and add new definitions
12
18
*
13
19
* This method takes as argument the annotated definition.
14
20
* It returns a non-empty list containing the modified version of the annotated definition.
15
21
* The new tree for the definition must use the original symbol.
16
22
* New definitions can be added to the list before or after the transformed definitions, this order
17
- * will be retained.
23
+ * will be retained. New definitions will not be visible from outside the macro expansion.
18
24
*
19
- * All definitions in the result must have the same owner. The owner can be recovered from `tree.symbol.owner`.
25
+ * #### Restrictions
26
+ * - All definitions in the result must have the same owner. The owner can be recovered from `Symbol.spliceOwner`.
27
+ * - Special case: an annotated top-level `def`, `val`, `var`, `lazy val` can return a `class`/`object`
28
+ definition that is owned by the package or package object.
29
+ * - Can not return a `type`.
30
+ * - Annotated top-level `class`/`object` can not return top-level `def`, `val`, `var`, `lazy val`.
31
+ * - Can not see new definition in user written code.
20
32
*
21
- * The result cannot add new `class`, `object` or `type` definition. This limitation will be relaxed in the future.
33
+ * #### Good practices
34
+ * - Make your new definitions private if you can.
35
+ * - New definitions added as class members should use a fresh name (`Symbol.freshName`) to avoid collisions.
36
+ * - New top-level definitions should use a fresh name (`Symbol.freshName`) that includes the name of the annotated
37
+ * member as a prefix to avoid collisions of definitions added in other files.
22
38
*
23
- * IMPORTANT: When developing and testing a macro annotation, you must enable `-Xcheck-macros` and `-Ycheck:all`.
39
+ * ** IMPORTANT** : When developing and testing a macro annotation, you must enable `-Xcheck-macros` and `-Ycheck:all`.
24
40
*
25
- * Example 1:
41
+ * #### Example 1
26
42
* This example shows how to modify a `def` and add a `val` next to it using a macro annotation.
27
43
* ```scala
28
44
* import scala.quoted.*
@@ -54,7 +70,10 @@ trait MacroAnnotation extends StaticAnnotation:
54
70
* List(tree)
55
71
* ```
56
72
* with this macro annotation a user can write
57
- * ```scala sc:nocompile
73
+ * ```scala
74
+ * //{
75
+ * class memoize extends scala.annotation.StaticAnnotation
76
+ * //}
58
77
* @memoize
59
78
* def fib(n: Int): Int =
60
79
* println(s"compute fib of $n")
@@ -74,7 +93,7 @@ trait MacroAnnotation extends StaticAnnotation:
74
93
* )
75
94
* ```
76
95
*
77
- * Example 2:
96
+ * #### Example 2
78
97
* This example shows how to modify a `class` using a macro annotation.
79
98
* It shows how to override inherited members and add new ones.
80
99
* ```scala
@@ -164,7 +183,10 @@ trait MacroAnnotation extends StaticAnnotation:
164
183
* }
165
184
* ```
166
185
* with this macro annotation a user can write
167
- * ```scala sc:nocompile
186
+ * ```scala
187
+ * //{
188
+ * class equals extends scala.annotation.StaticAnnotation
189
+ * //}
168
190
* @equals class User(val name: String, val id: Int)
169
191
* ```
170
192
* and the macro will modify the class definition to generate the following code
@@ -184,5 +206,7 @@ trait MacroAnnotation extends StaticAnnotation:
184
206
*
185
207
* @param Quotes Implicit instance of Quotes used for tree reflection
186
208
* @param tree Tree that will be transformed
209
+ *
210
+ * @syntax markdown
187
211
*/
188
212
def transform (using Quotes )(tree : quotes.reflect.Definition ): List [quotes.reflect.Definition ]
0 commit comments