Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 51c7a41

Browse files
Macro annotations class modifications (part 2)
Enable modification of classes with `MacroAnnotation`: * Can annotate `class` to transform it * Can annotate `object` to transform the companion class Supported class modifications: * Modify the implementations of `def`, `val`, `var`, `lazy val`, `class`, `object` in the class * Add new `def`, `val`, `var`, `lazy val`, `class`, `object` members to the class * Add a new override for a `def`, `val`, `var`, `lazy val` members in the class Restrictions: * An annotation on a top-level class cannot return a top-level `def`, `val`, `var`, `lazy val`
1 parent 07e395d commit 51c7a41

File tree

33 files changed

+556
-135
lines changed

33 files changed

+556
-135
lines changed

‎compiler/src/dotty/tools/dotc/transform/MacroAnnotations.scala‎

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import dotty.tools.dotc.config.Printers.{macroAnnot => debug}
99
import dotty.tools.dotc.core.Annotations.*
1010
import dotty.tools.dotc.core.Contexts.*
1111
import dotty.tools.dotc.core.Decorators.*
12+
import dotty.tools.dotc.core.Decorators.*
1213
import dotty.tools.dotc.core.DenotTransformers.DenotTransformer
1314
import dotty.tools.dotc.core.Flags.*
1415
import dotty.tools.dotc.core.MacroClassLoader
@@ -29,14 +30,10 @@ class MacroAnnotations(thisPhase: DenotTransformer):
2930
def expandAnnotations(tree: MemberDef)(using Context): List[DefTree] =
3031
if !hasMacroAnnotation(tree.symbol) then
3132
List(tree)
32-
else if tree.symbol.is(Module) then
33-
if tree.symbol.isClass then // error only reported on module class
34-
report.error("macro annotations are not supported on object", tree)
35-
List(tree)
36-
else if tree.symbol.isClass then
37-
report.error("macro annotations are not supported on class", tree)
33+
else if tree.symbol.is(Module) && !tree.symbol.isClass then
34+
// only class is transformed
3835
List(tree)
39-
else if tree.symbol.isType then
36+
else if tree.symbol.isType &&!tree.symbol.isClass then
4037
report.error("macro annotations are not supported on type", tree)
4138
List(tree)
4239
else
@@ -70,7 +67,6 @@ class MacroAnnotations(thisPhase: DenotTransformer):
7067
else
7168
tree
7269
}
73-
7470
allTrees += transformedTree
7571
insertedAfter.foreach(allTrees.++=)
7672

@@ -98,11 +94,13 @@ class MacroAnnotations(thisPhase: DenotTransformer):
9894
private def checkAndEnter(newTree: Tree, annotated: Symbol, annot: Annotation)(using Context) =
9995
val sym = newTree.symbol
10096
if sym.isClass then
101-
report.error("Generating classes is not supported", annot.tree)
97+
report.error(i"macro annotation returning a `class` is not yet supported. $annot tried to add $sym", annot.tree)
10298
else if sym.isType then
103-
report.error("Generating type is not supported", annot.tree)
99+
report.error(i"macro annotation cannot return a `type`. $annot tried to add $sym", annot.tree)
104100
else if sym.owner != annotated.owner then
105101
report.error(i"macro annotation $annot added $sym with an inconsistent owner. Expected it to be owned by ${annotated.owner} but was owned by ${sym.owner}.", annot.tree)
102+
else if annotated.isClass && annotated.owner.is(Package) /*&& !sym.isClass*/ then
103+
report.error(i"macro annotation can not add top-level ${sym.showKind}. $annot tried to add $sym.", annot.tree)
106104
else
107105
sym.enteredAfter(thisPhase)
108106

Lines changed: 78 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,68 +1,98 @@
11

2-
-- Error: tests/neg-macros/annot-error-annot/Test_2.scala:18:6 ---------------------------------------------------------
3-
17 | @error
4-
18 | val vMember: Int = 1 // error
2+
-- Error: tests/neg-macros/annot-error-annot/Test_2.scala:17:6 ---------------------------------------------------------
3+
16 |@error
4+
17 |class cGlobal // error
5+
|^
6+
|MACRO ERROR
7+
-- Error: tests/neg-macros/annot-error-annot/Test_2.scala:20:7 ---------------------------------------------------------
8+
19 |@error
9+
20 |object oGlobal // error
10+
|^
11+
|MACRO ERROR
12+
-- Error: tests/neg-macros/annot-error-annot/Test_2.scala:24:6 ---------------------------------------------------------
13+
23 | @error
14+
24 | val vMember: Int = 1 // error
515
| ^
616
| MACRO ERROR
7-
-- Error: tests/neg-macros/annot-error-annot/Test_2.scala:20:11 --------------------------------------------------------
8-
19 | @error
9-
20 | lazy val lvMember: Int = 1 // error
17+
-- Error: tests/neg-macros/annot-error-annot/Test_2.scala:26:11 --------------------------------------------------------
18+
25 | @error
19+
26 | lazy val lvMember: Int = 1 // error
1020
| ^
1121
| MACRO ERROR
12-
-- Error: tests/neg-macros/annot-error-annot/Test_2.scala:22:6 ---------------------------------------------------------
13-
21 | @error
14-
22 | def dMember: Int = 1 // error
22+
-- Error: tests/neg-macros/annot-error-annot/Test_2.scala:28:6 ---------------------------------------------------------
23+
27 | @error
24+
28 | def dMember: Int = 1 // error
1525
| ^
1626
| MACRO ERROR
17-
-- Error: tests/neg-macros/annot-error-annot/Test_2.scala:24:8 ---------------------------------------------------------
18-
23 | @error
19-
24 | given gMember: Int = 1 // error
27+
-- Error: tests/neg-macros/annot-error-annot/Test_2.scala:30:8 ---------------------------------------------------------
28+
29 | @error
29+
30 | given gMember: Int = 1 // error
2030
| ^
2131
| MACRO ERROR
22-
-- Error: tests/neg-macros/annot-error-annot/Test_2.scala:26:8 ---------------------------------------------------------
23-
25 | @error
24-
26 | given gMember2: Num[Int] with // error: object not supported (TODO support)
32+
-- Error: tests/neg-macros/annot-error-annot/Test_2.scala:32:8 ---------------------------------------------------------
33+
31 | @error
34+
32 | given gMember2: Num[Int] with // error
35+
| ^
36+
| MACRO ERROR
37+
33 | def zero = 0
38+
-- Error: tests/neg-macros/annot-error-annot/Test_2.scala:35:8 ---------------------------------------------------------
39+
34 | @error
40+
35 | given gMember3(using DummyImplicit): Num[Int] with // error
41+
| ^
42+
| MACRO ERROR
43+
36 | def zero = 0
44+
-- Error: tests/neg-macros/annot-error-annot/Test_2.scala:39:8 ---------------------------------------------------------
45+
38 | @error
46+
39 | class cMember // error
2547
| ^
26-
| macro annotations are not supported on object
27-
27 | def zero = 0
28-
-- Error: tests/neg-macros/annot-error-annot/Test_2.scala:29:8 ---------------------------------------------------------
29-
28 | @error
30-
29 | given gMember3(using DummyImplicit): Num[Int] with // error: class not supported (TODO support)
48+
| MACRO ERROR
49+
-- Error: tests/neg-macros/annot-error-annot/Test_2.scala:42:9 ---------------------------------------------------------
50+
41 | @error
51+
42 | object oMember // error
3152
| ^
32-
| macro annotations are not supported on class
33-
30 | def zero = 0
34-
-- Error: tests/neg-macros/annot-error-annot/Test_2.scala:34:8 ---------------------------------------------------------
35-
33 | @error
36-
34 | val vLocal: Int = 1 // error
53+
| MACRO ERROR
54+
-- Error: tests/neg-macros/annot-error-annot/Test_2.scala:46:8 ---------------------------------------------------------
55+
45 | @error
56+
46 | val vLocal: Int = 1 // error
3757
| ^
3858
| MACRO ERROR
39-
-- Error: tests/neg-macros/annot-error-annot/Test_2.scala:36:13 --------------------------------------------------------
40-
35 | @error
41-
36 | lazy val lvLocal: Int = 1 // error
59+
-- Error: tests/neg-macros/annot-error-annot/Test_2.scala:48:13 --------------------------------------------------------
60+
47 | @error
61+
48 | lazy val lvLocal: Int = 1 // error
4262
| ^
4363
| MACRO ERROR
44-
-- Error: tests/neg-macros/annot-error-annot/Test_2.scala:38:8 ---------------------------------------------------------
45-
37 | @error
46-
38 | def dLocal: Int = 1 // error
64+
-- Error: tests/neg-macros/annot-error-annot/Test_2.scala:50:8 ---------------------------------------------------------
65+
49 | @error
66+
50 | def dLocal: Int = 1 // error
4767
| ^
4868
| MACRO ERROR
49-
-- Error: tests/neg-macros/annot-error-annot/Test_2.scala:40:10 --------------------------------------------------------
50-
39 | @error
51-
40 | given gLocal: Int = 1 // error
69+
-- Error: tests/neg-macros/annot-error-annot/Test_2.scala:52:10 --------------------------------------------------------
70+
51 | @error
71+
52 | given gLocal: Int = 1 // error
5272
| ^
5373
| MACRO ERROR
54-
-- Error: tests/neg-macros/annot-error-annot/Test_2.scala:42:10 --------------------------------------------------------
55-
41 | @error
56-
42 | given gLocal2: Num[Int] with // error: object not supported (TODO support)
74+
-- Error: tests/neg-macros/annot-error-annot/Test_2.scala:54:10 --------------------------------------------------------
75+
53 | @error
76+
54 | given gLocal2: Num[Int] with // error
5777
| ^
58-
| macro annotations are not supported on object
59-
43 | def zero = 0
60-
-- Error: tests/neg-macros/annot-error-annot/Test_2.scala:45:10 --------------------------------------------------------
61-
44 | @error
62-
45 | given gLocal3(using DummyImplicit): Num[Int] with // error: class not supported (TODO support)
78+
| MACRO ERROR
79+
55 | def zero = 0
80+
-- Error: tests/neg-macros/annot-error-annot/Test_2.scala:57:10 --------------------------------------------------------
81+
56 | @error
82+
57 | given gLocal3(using DummyImplicit): Num[Int] with // error
6383
| ^
64-
| macro annotations are not supported on class
65-
46 | def zero = 0
84+
| MACRO ERROR
85+
58 | def zero = 0
86+
-- Error: tests/neg-macros/annot-error-annot/Test_2.scala:61:10 --------------------------------------------------------
87+
60 | @error
88+
61 | class cLocal // error
89+
| ^
90+
| MACRO ERROR
91+
-- Error: tests/neg-macros/annot-error-annot/Test_2.scala:63:11 --------------------------------------------------------
92+
62 | @error
93+
63 | object oLocal // error
94+
| ^
95+
| MACRO ERROR
6696
-- Error: tests/neg-macros/annot-error-annot/Test_2.scala:2:4 ----------------------------------------------------------
6797
1 |@error
6898
2 |val vGlobal: Int = 1 // error
@@ -85,13 +115,13 @@
85115
|MACRO ERROR
86116
-- Error: tests/neg-macros/annot-error-annot/Test_2.scala:10:6 ---------------------------------------------------------
87117
9 |@error
88-
10 |given gGlobal2: Num[Int] with // error: object not supported (TODO support)
118+
10 |given gGlobal2: Num[Int] with // error
89119
|^
90-
|macro annotations are not supported on object
120+
|MACRO ERROR
91121
11 | def zero = 0
92122
-- Error: tests/neg-macros/annot-error-annot/Test_2.scala:13:6 ---------------------------------------------------------
93123
12 |@error
94-
13 |given gGlobal3(using DummyImplicit): Num[Int] with // error: class not supported (TODO support)
124+
13 |given gGlobal3(using DummyImplicit): Num[Int] with // error
95125
|^
96-
|macro annotations are not supported on class
126+
|MACRO ERROR
97127
14 | def zero = 0

‎tests/neg-macros/annot-error-annot/Test_2.scala‎

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,18 @@ def dGlobal: Int = 1 // error
77
@error
88
given gGlobal: Int = 1 // error
99
@error
10-
given gGlobal2: Num[Int] with // error: object not supported (TODO support)
10+
given gGlobal2: Num[Int] with // error
1111
def zero = 0
1212
@error
13-
given gGlobal3(using DummyImplicit): Num[Int] with // error: class not supported (TODO support)
13+
given gGlobal3(using DummyImplicit): Num[Int] with // error
1414
def zero = 0
1515

16+
@error
17+
class cGlobal // error
18+
19+
@error
20+
object oGlobal // error
21+
1622
class B:
1723
@error
1824
val vMember: Int = 1 // error
@@ -23,12 +29,18 @@ class B:
2329
@error
2430
given gMember: Int = 1 // error
2531
@error
26-
given gMember2: Num[Int] with // error: object not supported (TODO support)
32+
given gMember2: Num[Int] with // error
2733
def zero = 0
2834
@error
29-
given gMember3(using DummyImplicit): Num[Int] with // error: class not supported (TODO support)
35+
given gMember3(using DummyImplicit): Num[Int] with // error
3036
def zero = 0
3137

38+
@error
39+
class cMember // error
40+
41+
@error
42+
object oMember // error
43+
3244
def locals: Unit =
3345
@error
3446
val vLocal: Int = 1 // error
@@ -39,11 +51,16 @@ class B:
3951
@error
4052
given gLocal: Int = 1 // error
4153
@error
42-
given gLocal2: Num[Int] with // error: object not supported (TODO support)
54+
given gLocal2: Num[Int] with // error
4355
def zero = 0
4456
@error
45-
given gLocal3(using DummyImplicit): Num[Int] with // error: class not supported (TODO support)
57+
given gLocal3(using DummyImplicit): Num[Int] with // error
4658
def zero = 0
59+
60+
@error
61+
class cLocal // error
62+
@error
63+
object oLocal // error
4764
()
4865

4966
trait Num[T]:
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
2+
-- Error: tests/neg-macros/annot-mod-class-add-top-method/Test_2.scala:1:0 ---------------------------------------------
3+
1 |@addTopLevelMethod // error
4+
|^^^^^^^^^^^^^^^^^^
5+
|macro annotation can not add top-level method. @addTopLevelMethod tried to add method toLevelMethod1ドル.
6+
-- Error: tests/neg-macros/annot-mod-class-add-top-method/Test_2.scala:4:0 ---------------------------------------------
7+
4 |@addTopLevelMethod // error
8+
|^^^^^^^^^^^^^^^^^^
9+
|macro annotation can not add top-level method. @addTopLevelMethod tried to add method toLevelMethod2ドル.
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import scala.annotation.{experimental, MacroAnnotation}
2+
import scala.quoted._
3+
import scala.collection.mutable
4+
5+
@experimental
6+
class addTopLevelMethod extends MacroAnnotation:
7+
def transform(using Quotes)(tree: quotes.reflect.Definition): List[quotes.reflect.Definition] =
8+
import quotes.reflect._
9+
tree match
10+
case ClassDef(name, ctr, parents, self, body) =>
11+
val cls = tree.symbol
12+
val methType = MethodType(Nil)(_ => Nil, _ => TypeRepr.of[Int])
13+
val methSym = Symbol.newUniqueMethod(cls.owner, "toLevelMethod", methType, Flags.EmptyFlags, Symbol.noSymbol)
14+
val methDef = DefDef(methSym, _ => Some(Literal(IntConstant(1))))
15+
List(methDef, tree)
16+
case _ =>
17+
report.error("Annotation only supports `class`")
18+
List(tree)
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
@addTopLevelMethod // error
2+
class Foo
3+
4+
@addTopLevelMethod // error
5+
object Foo
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
2+
-- Error: tests/neg-macros/annot-mod-class-add-top-val/Test_2.scala:1:0 ------------------------------------------------
3+
1 |@addTopLevelVal // error
4+
|^^^^^^^^^^^^^^^
5+
|macro annotation can not add top-level value. @addTopLevelVal tried to add value toLevelvalod1ドル.
6+
-- Error: tests/neg-macros/annot-mod-class-add-top-val/Test_2.scala:4:0 ------------------------------------------------
7+
4 |@addTopLevelVal // error
8+
|^^^^^^^^^^^^^^^
9+
|macro annotation can not add top-level value. @addTopLevelVal tried to add value toLevelvalod2ドル.
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import scala.annotation.{experimental, MacroAnnotation}
2+
import scala.quoted._
3+
import scala.collection.mutable
4+
5+
@experimental
6+
class addTopLevelVal extends MacroAnnotation:
7+
def transform(using Quotes)(tree: quotes.reflect.Definition): List[quotes.reflect.Definition] =
8+
import quotes.reflect._
9+
tree match
10+
case ClassDef(name, ctr, parents, self, body) =>
11+
val cls = tree.symbol
12+
val valSym = Symbol.newUniqueVal(cls.owner, "toLevelvalod", TypeRepr.of[Int], Flags.EmptyFlags, Symbol.noSymbol)
13+
val valDef = DefDef(valSym, _ => Some(Literal(IntConstant(1))))
14+
List(valDef, tree)
15+
case _ =>
16+
report.error("Annotation only supports `class`")
17+
List(tree)
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
@addTopLevelVal // error
2+
class Foo
3+
4+
@addTopLevelVal // error
5+
object Foo

‎tests/neg-macros/annot-on-class.check‎

Lines changed: 0 additions & 17 deletions
This file was deleted.

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /