@@ -67,29 +67,41 @@ trait ArgsMacros {
67
67
object Util {
68
68
def isSynthetic (c : Reflection )(s : c.Symbol ) = isSyntheticName(getName(c)(s))
69
69
def isSyntheticName (name : String ) = {
70
- name == " <init>" || (name.startsWith(" <local " ) && name.endsWith(" >" )) || name == " $anonfun"
70
+ name == " <init>" || (name.startsWith(" <local " ) && name.endsWith(" >" )) || name == " $anonfun" || name == " macro "
71
71
}
72
72
def getName (c : Reflection )(s : c.Symbol ) = {
73
- import c .given
73
+ import c .{ given _ }
74
74
s.name.trim
75
75
.stripSuffix(" $" ) // meh
76
76
}
77
77
}
78
78
79
79
object Macros {
80
80
81
- def actualOwner (c : Reflection )(owner : c.Symbol ): c.Symbol = {
82
- import c .given
81
+ def findOwner (c : Reflection )(owner : c.Symbol , skipIf : ( c : Reflection ) => (c. Symbol ) => Boolean ): c.Symbol = {
82
+ import c .{ given _ }
83
83
var owner0 = owner
84
- // second condition is meh
85
- while (Util .isSynthetic(c)(owner0) || Util .getName(c)(owner0) == " ev" ) {
86
- owner0 = owner0.owner
87
- }
84
+ while (skipIf(c)(owner0)) owner0 = owner0.owner
88
85
owner0
89
86
}
90
87
91
- def nameImpl (given ctx : QuoteContext ): Expr [Name ] = {
92
- import ctx .tasty .given
88
+ def actualOwner (c : Reflection )(owner : c.Symbol ): c.Symbol =
89
+ findOwner(c)(owner, c => owner0 => Util .isSynthetic(c)(owner0) || Util .getName(c)(owner0) == " ev" )
90
+
91
+ /**
92
+ * In Scala 3, macro `mcr()` is expanded to:
93
+ *
94
+ * val macro = ...
95
+ * macro
96
+ *
97
+ * Where n is an ordinal. This method returns the first owner that is not
98
+ * such a synthetic variable.
99
+ */
100
+ def nonMacroOwner (c : Reflection )(owner : c.Symbol ): c.Symbol =
101
+ findOwner(c)(owner, c => owner0 => {import c .{given _ }; owner0.flags.is(c.Flags .Macro ) && Util .getName(c)(owner0) == " macro" })
102
+
103
+ def nameImpl (using ctx : QuoteContext ): Expr [Name ] = {
104
+ import ctx .tasty .{given _ }
93
105
val owner = actualOwner(ctx.tasty)(ctx.tasty.rootContext.owner)
94
106
val simpleName = Util .getName(ctx.tasty)(owner)
95
107
' {Name ($ {Expr (simpleName)})}
@@ -102,15 +114,15 @@ object Macros {
102
114
else
103
115
s
104
116
105
- def nameMachineImpl (given ctx : QuoteContext ): Expr [Name .Machine ] = {
106
- import ctx .tasty .given
107
- val owner = ctx.tasty. rootContext.owner
117
+ def nameMachineImpl (using ctx : QuoteContext ): Expr [Name .Machine ] = {
118
+ import ctx .tasty .{ given _ }
119
+ val owner = nonMacroOwner( ctx.tasty)(ctx.tasty. rootContext.owner)
108
120
val simpleName = adjustName(Util .getName(ctx.tasty)(owner))
109
121
' {Name .Machine ($ {Expr (simpleName)})}
110
122
}
111
123
112
- def fullNameImpl (given ctx : QuoteContext ): Expr [FullName ] = {
113
- import ctx .tasty .given
124
+ def fullNameImpl (using ctx : QuoteContext ): Expr [FullName ] = {
125
+ import ctx .tasty .{ given _ }
114
126
@ annotation.tailrec def cleanChunk (chunk : String ): String =
115
127
val refined = chunk.stripPrefix(" _$" ).stripSuffix(" $" )
116
128
if chunk != refined then cleanChunk(refined) else refined
@@ -125,9 +137,9 @@ object Macros {
125
137
' {FullName ($ {Expr (fullName)})}
126
138
}
127
139
128
- def fullNameMachineImpl (given ctx : QuoteContext ): Expr [FullName .Machine ] = {
129
- import ctx .tasty .given
130
- val owner = ctx.tasty. rootContext.owner
140
+ def fullNameMachineImpl (using ctx : QuoteContext ): Expr [FullName .Machine ] = {
141
+ import ctx .tasty .{ given _ }
142
+ val owner = nonMacroOwner( ctx.tasty)(ctx.tasty. rootContext.owner)
131
143
val fullName = owner.fullName.trim
132
144
.split(" \\ ." , - 1 )
133
145
.map(_.stripPrefix(" _$" ).stripSuffix(" $" )) // meh
@@ -136,39 +148,39 @@ object Macros {
136
148
' {FullName .Machine ($ {Expr (fullName)})}
137
149
}
138
150
139
- def fileImpl (given ctx : QuoteContext ): Expr [sourcecode.File ] = {
140
- import ctx .tasty .given
151
+ def fileImpl (using ctx : QuoteContext ): Expr [sourcecode.File ] = {
152
+ import ctx .tasty .{ given _ }
141
153
val file = ctx.tasty.rootPosition.sourceFile.jpath.toAbsolutePath.toString
142
154
' {sourcecode.File ($ {Expr (file)})}
143
155
}
144
156
145
- def fileNameImpl (given ctx : QuoteContext ): Expr [sourcecode.FileName ] = {
146
- import ctx .tasty .given
157
+ def fileNameImpl (using ctx : QuoteContext ): Expr [sourcecode.FileName ] = {
158
+ import ctx .tasty .{ given _ }
147
159
val name = ctx.tasty.rootPosition.sourceFile.jpath.getFileName.toString
148
160
' {sourcecode.FileName ($ {Expr (name)})}
149
161
}
150
162
151
- def lineImpl (given ctx : QuoteContext ): Expr [sourcecode.Line ] = {
152
- import ctx .tasty .given
163
+ def lineImpl (using ctx : QuoteContext ): Expr [sourcecode.Line ] = {
164
+ import ctx .tasty .{ given _ }
153
165
val line = ctx.tasty.rootPosition.startLine + 1
154
166
' {sourcecode.Line ($ {Expr (line)})}
155
167
}
156
168
157
- def enclosingImpl (given ctx : QuoteContext ): Expr [Enclosing ] = {
169
+ def enclosingImpl (using ctx : QuoteContext ): Expr [Enclosing ] = {
158
170
val path = enclosing(ctx.tasty)(
159
171
! Util .isSynthetic(ctx.tasty)(_)
160
172
)
161
173
162
174
' {Enclosing ($ {Expr (path)})}
163
175
}
164
176
165
- def enclosingMachineImpl (given ctx : QuoteContext ): Expr [Enclosing .Machine ] = {
177
+ def enclosingMachineImpl (using ctx : QuoteContext ): Expr [Enclosing .Machine ] = {
166
178
val path = enclosing(ctx.tasty, machine = true )(_ => true )
167
179
' {Enclosing .Machine ($ {Expr (path)})}
168
180
}
169
181
170
- def pkgImpl (given ctx : QuoteContext ): Expr [Pkg ] = {
171
- import ctx .tasty .given
182
+ def pkgImpl (using ctx : QuoteContext ): Expr [Pkg ] = {
183
+ import ctx .tasty .{ given _ }
172
184
val path = enclosing(ctx.tasty) {
173
185
case s if s.isPackageDef => true
174
186
case _ => false
@@ -177,8 +189,8 @@ object Macros {
177
189
' {Pkg ($ {Expr (path)})}
178
190
}
179
191
180
- def argsImpl (given ctx : QuoteContext ): Expr [Args ] = {
181
- import ctx .tasty .{ _ , given }
192
+ def argsImpl (using ctx : QuoteContext ): Expr [Args ] = {
193
+ import ctx .tasty .{ _ , given _ }
182
194
183
195
val param : List [List [ctx.tasty.ValDef ]] = {
184
196
def nearestEnclosingMethod (owner : ctx.tasty.Symbol ): List [List [ctx.tasty.ValDef ]] =
@@ -207,8 +219,8 @@ object Macros {
207
219
}
208
220
209
221
210
- def text [T : Type ](v : Expr [T ])(given ctx : QuoteContext ): Expr [sourcecode.Text [T ]] = {
211
- import ctx .tasty .given
222
+ def text [T : Type ](v : Expr [T ])(using ctx : QuoteContext ): Expr [sourcecode.Text [T ]] = {
223
+ import ctx .tasty .{ given _ }
212
224
val txt = v.unseal.pos.sourceCode
213
225
' {sourcecode.Text [T ]($v, $ {Expr (txt)})}
214
226
}
@@ -222,11 +234,13 @@ object Macros {
222
234
}
223
235
224
236
def enclosing (c : Reflection , machine : Boolean = false )(filter : c.Symbol => Boolean ): String = {
225
- import c .{ _ , given }
237
+ import c .{ _ , given _ }
226
238
227
239
var current = c.rootContext.owner
228
240
if (! machine)
229
241
current = actualOwner(c)(current)
242
+ else
243
+ current = nonMacroOwner(c)(current)
230
244
var path = List .empty[Chunk ]
231
245
while (current != Symbol .noSymbol && current != defn.RootPackage && current != defn.RootClass ){
232
246
if (filter(current)) {
0 commit comments