@@ -15,7 +15,7 @@ import dotty.tools.dotc.core.StdNames.str.MODULE_INSTANCE_FIELD
15
15
import dotty .tools .dotc .core .quoted ._
16
16
import dotty .tools .dotc .core .Types ._
17
17
import dotty .tools .dotc .core .Symbols ._
18
- import dotty .tools .dotc .core .TypeErasure
18
+ import dotty .tools .dotc .core .{ NameKinds , TypeErasure }
19
19
import dotty .tools .dotc .core .Constants .Constant
20
20
import dotty .tools .dotc .tastyreflect .TastyImpl
21
21
@@ -105,14 +105,18 @@ object Splicer {
105
105
protected def interpretVarargs (args : List [Object ])(implicit env : Env ): Object =
106
106
args.toSeq
107
107
108
- protected def interpretTastyContext ()(implicit env : Env ): Object =
108
+ protected def interpretTastyContext ()(implicit env : Env ): Object = {
109
109
new TastyImpl (ctx) {
110
110
override def rootPosition : SourcePosition = pos
111
111
}
112
+ }
112
113
113
- protected def interpretStaticMethodCall (fn : Tree , args : => List [Object ])(implicit env : Env ): Object = {
114
- val instance = loadModule(fn.symbol.owner)
115
- val method = getMethod(instance.getClass, fn.symbol.name, paramsSig(fn.symbol))
114
+ protected def interpretStaticMethodCall (fn : Symbol , args : => List [Object ])(implicit env : Env ): Object = {
115
+ val instance = loadModule(fn.owner)
116
+ val name =
117
+ if (! defn.isImplicitFunctionType(fn.info.finalResultType)) fn.name
118
+ else NameKinds .DirectMethodName (fn.name.asTermName) // Call implicit function type direct method
119
+ val method = getMethod(instance.getClass, name, paramsSig(fn))
116
120
stopIfRuntimeException(method.invoke(instance, args : _* ))
117
121
}
118
122
@@ -190,50 +194,57 @@ object Splicer {
190
194
191
195
/** List of classes of the parameters of the signature of `sym` */
192
196
private def paramsSig (sym : Symbol ): List [Class [_]] = {
193
- TypeErasure .erasure(sym.info) match {
194
- case meth : MethodType =>
195
- meth.paramInfos.map { param =>
196
- def arrayDepth (tpe : Type , depth : Int ): (Type , Int ) = tpe match {
197
- case JavaArrayType (elemType) => arrayDepth(elemType, depth + 1 )
198
- case _ => (tpe, depth)
199
- }
200
- def javaArraySig (tpe : Type ): String = {
201
- val (elemType, depth) = arrayDepth(tpe, 0 )
202
- val sym = elemType.classSymbol
203
- val suffix =
204
- if (sym == defn.BooleanClass ) " Z"
205
- else if (sym == defn.ByteClass ) " B"
206
- else if (sym == defn.ShortClass ) " S"
207
- else if (sym == defn.IntClass ) " I"
208
- else if (sym == defn.LongClass ) " J"
209
- else if (sym == defn.FloatClass ) " F"
210
- else if (sym == defn.DoubleClass ) " D"
211
- else if (sym == defn.CharClass ) " C"
212
- else " L" + javaSig(elemType) + " ;"
213
- (" [" * depth) + suffix
214
- }
215
- def javaSig (tpe : Type ): String = tpe match {
216
- case tpe : JavaArrayType => javaArraySig(tpe)
217
- case _ =>
218
- // Take the flatten name of the class and the full package name
219
- val pack = tpe.classSymbol.topLevelClass.owner
220
- val packageName = if (pack == defn.EmptyPackageClass ) " " else pack.fullName + " ."
221
- packageName + tpe.classSymbol.fullNameSeparated(FlatName ).toString
222
- }
223
-
224
- val sym = param.classSymbol
225
- if (sym == defn.BooleanClass ) classOf [Boolean ]
226
- else if (sym == defn.ByteClass ) classOf [Byte ]
227
- else if (sym == defn.CharClass ) classOf [Char ]
228
- else if (sym == defn.ShortClass ) classOf [Short ]
229
- else if (sym == defn.IntClass ) classOf [Int ]
230
- else if (sym == defn.LongClass ) classOf [Long ]
231
- else if (sym == defn.FloatClass ) classOf [Float ]
232
- else if (sym == defn.DoubleClass ) classOf [Double ]
233
- else java.lang.Class .forName(javaSig(param), false , classLoader)
234
- }
197
+ def paramClass (param : Type ): Class [_] = {
198
+ def arrayDepth (tpe : Type , depth : Int ): (Type , Int ) = tpe match {
199
+ case JavaArrayType (elemType) => arrayDepth(elemType, depth + 1 )
200
+ case _ => (tpe, depth)
201
+ }
202
+ def javaArraySig (tpe : Type ): String = {
203
+ val (elemType, depth) = arrayDepth(tpe, 0 )
204
+ val sym = elemType.classSymbol
205
+ val suffix =
206
+ if (sym == defn.BooleanClass ) " Z"
207
+ else if (sym == defn.ByteClass ) " B"
208
+ else if (sym == defn.ShortClass ) " S"
209
+ else if (sym == defn.IntClass ) " I"
210
+ else if (sym == defn.LongClass ) " J"
211
+ else if (sym == defn.FloatClass ) " F"
212
+ else if (sym == defn.DoubleClass ) " D"
213
+ else if (sym == defn.CharClass ) " C"
214
+ else " L" + javaSig(elemType) + " ;"
215
+ (" [" * depth) + suffix
216
+ }
217
+ def javaSig (tpe : Type ): String = tpe match {
218
+ case tpe : JavaArrayType => javaArraySig(tpe)
219
+ case _ =>
220
+ // Take the flatten name of the class and the full package name
221
+ val pack = tpe.classSymbol.topLevelClass.owner
222
+ val packageName = if (pack == defn.EmptyPackageClass ) " " else pack.fullName + " ."
223
+ packageName + tpe.classSymbol.fullNameSeparated(FlatName ).toString
224
+ }
225
+
226
+ val sym = param.classSymbol
227
+ if (sym == defn.BooleanClass ) classOf [Boolean ]
228
+ else if (sym == defn.ByteClass ) classOf [Byte ]
229
+ else if (sym == defn.CharClass ) classOf [Char ]
230
+ else if (sym == defn.ShortClass ) classOf [Short ]
231
+ else if (sym == defn.IntClass ) classOf [Int ]
232
+ else if (sym == defn.LongClass ) classOf [Long ]
233
+ else if (sym == defn.FloatClass ) classOf [Float ]
234
+ else if (sym == defn.DoubleClass ) classOf [Double ]
235
+ else java.lang.Class .forName(javaSig(param), false , classLoader)
236
+ }
237
+ val extraParams = sym.info.finalResultType.widenDealias match {
238
+ case tp : AppliedType if defn.isImplicitFunctionType(tp) =>
239
+ // Call implicit function type direct method
240
+ tp.args.init.map(arg => TypeErasure .erasure(arg))
235
241
case _ => Nil
236
242
}
243
+ val allParams = TypeErasure .erasure(sym.info) match {
244
+ case meth : MethodType => (meth.paramInfos ::: extraParams)
245
+ case _ => extraParams
246
+ }
247
+ allParams.map(paramClass)
237
248
}
238
249
239
250
/** Exception that stops interpretation if some issue is found */
@@ -253,7 +264,8 @@ object Splicer {
253
264
protected def interpretLiteral (value : Any )(implicit env : Env ): Boolean = true
254
265
protected def interpretVarargs (args : List [Boolean ])(implicit env : Env ): Boolean = args.forall(identity)
255
266
protected def interpretTastyContext ()(implicit env : Env ): Boolean = true
256
- protected def interpretStaticMethodCall (fn : tpd.Tree , args : => List [Boolean ])(implicit env : Env ): Boolean = args.forall(identity)
267
+ protected def interpretQuoteContext ()(implicit env : Env ): Boolean = true
268
+ protected def interpretStaticMethodCall (fn : Symbol , args : => List [Boolean ])(implicit env : Env ): Boolean = args.forall(identity)
257
269
protected def interpretModuleAccess (fn : Tree )(implicit env : Env ): Boolean = true
258
270
protected def interpretNew (fn : RefTree , args : => List [Boolean ])(implicit env : Env ): Boolean = args.forall(identity)
259
271
@@ -275,7 +287,7 @@ object Splicer {
275
287
protected def interpretLiteral (value : Any )(implicit env : Env ): Result
276
288
protected def interpretVarargs (args : List [Result ])(implicit env : Env ): Result
277
289
protected def interpretTastyContext ()(implicit env : Env ): Result
278
- protected def interpretStaticMethodCall (fn : Tree , args : => List [Result ])(implicit env : Env ): Result
290
+ protected def interpretStaticMethodCall (fn : Symbol , args : => List [Result ])(implicit env : Env ): Result
279
291
protected def interpretModuleAccess (fn : Tree )(implicit env : Env ): Result
280
292
protected def interpretNew (fn : RefTree , args : => List [Result ])(implicit env : Env ): Result
281
293
protected def unexpectedTree (tree : Tree )(implicit env : Env ): Result
@@ -298,11 +310,16 @@ object Splicer {
298
310
interpretNew(fn, args.map(interpretTree))
299
311
} else if (fn.symbol.isStatic) {
300
312
if (fn.symbol.is(Module )) interpretModuleAccess(fn)
301
- else interpretStaticMethodCall(fn, args.map(arg => interpretTree(arg)))
313
+ else interpretStaticMethodCall(fn.symbol , args.map(arg => interpretTree(arg)))
302
314
} else if (env.contains(fn.name)) {
303
315
env(fn.name)
304
316
} else {
305
- unexpectedTree(tree)
317
+ fn match {
318
+ case fn @ Select (Call (fn0, args0), _) if fn0.symbol.isStatic && fn.symbol.info.isImplicitMethod =>
319
+ // Call implicit function type direct method
320
+ interpretStaticMethodCall(fn0.symbol, (args0 ::: args).map(arg => interpretTree(arg)))
321
+ case _ => unexpectedTree(tree)
322
+ }
306
323
}
307
324
308
325
// Interpret `foo(j = x, i = y)` which it is expanded to
0 commit comments