@@ -10,12 +10,13 @@ import dotty.tools.dotc.core.Contexts._
10
10
import dotty .tools .dotc .core .Decorators ._
11
11
import dotty .tools .dotc .core .Flags ._
12
12
import dotty .tools .dotc .core .NameKinds .FlatName
13
- import dotty .tools .dotc .core .Names .Name
13
+ import dotty .tools .dotc .core .Names .{Name , TermName }
14
+ import dotty .tools .dotc .core .StdNames .nme
14
15
import dotty .tools .dotc .core .StdNames .str .MODULE_INSTANCE_FIELD
15
16
import dotty .tools .dotc .core .quoted ._
16
17
import dotty .tools .dotc .core .Types ._
17
18
import dotty .tools .dotc .core .Symbols ._
18
- import dotty .tools .dotc .core .TypeErasure
19
+ import dotty .tools .dotc .core .{ NameKinds , TypeErasure }
19
20
import dotty .tools .dotc .core .Constants .Constant
20
21
import dotty .tools .dotc .tastyreflect .TastyImpl
21
22
@@ -105,23 +106,30 @@ object Splicer {
105
106
protected def interpretVarargs (args : List [Object ])(implicit env : Env ): Object =
106
107
args.toSeq
107
108
108
- protected def interpretTastyContext ()(implicit env : Env ): Object =
109
+ protected def interpretTastyContext ()(implicit env : Env ): Object = {
109
110
new TastyImpl (ctx) {
110
111
override def rootPosition : SourcePosition = pos
111
112
}
113
+ }
112
114
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))
115
+ protected def interpretStaticMethodCall (fn : Symbol , args : => List [Object ])(implicit env : Env ): Object = {
116
+ val instance = loadModule(fn.owner)
117
+ def getDirectName (tp : Type , name : TermName ): TermName = tp.widenDealias match {
118
+ case tp : AppliedType if defn.isImplicitFunctionType(tp) =>
119
+ getDirectName(tp.args.last, NameKinds .DirectMethodName (name))
120
+ case _ => name
121
+ }
122
+ val name = getDirectName(fn.info.finalResultType, fn.name.asTermName)
123
+ val method = getMethod(instance.getClass, name, paramsSig(fn))
116
124
stopIfRuntimeException(method.invoke(instance, args : _* ))
117
125
}
118
126
119
- protected def interpretModuleAccess (fn : Tree )(implicit env : Env ): Object =
120
- loadModule(fn.symbol. moduleClass)
127
+ protected def interpretModuleAccess (fn : Symbol )(implicit env : Env ): Object =
128
+ loadModule(fn.moduleClass)
121
129
122
- protected def interpretNew (fn : RefTree , args : => List [Result ])(implicit env : Env ): Object = {
123
- val clazz = loadClass(fn.symbol. owner.fullName)
124
- val constr = clazz.getConstructor(paramsSig(fn.symbol ): _* )
130
+ protected def interpretNew (fn : Symbol , args : => List [Result ])(implicit env : Env ): Object = {
131
+ val clazz = loadClass(fn.owner.fullName)
132
+ val constr = clazz.getConstructor(paramsSig(fn): _* )
125
133
constr.newInstance(args : _* ).asInstanceOf [Object ]
126
134
}
127
135
@@ -190,50 +198,58 @@ object Splicer {
190
198
191
199
/** List of classes of the parameters of the signature of `sym` */
192
200
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
- }
201
+ def paramClass (param : Type ): Class [_] = {
202
+ def arrayDepth (tpe : Type , depth : Int ): (Type , Int ) = tpe match {
203
+ case JavaArrayType (elemType) => arrayDepth(elemType, depth + 1 )
204
+ case _ => (tpe, depth)
205
+ }
206
+ def javaArraySig (tpe : Type ): String = {
207
+ val (elemType, depth) = arrayDepth(tpe, 0 )
208
+ val sym = elemType.classSymbol
209
+ val suffix =
210
+ if (sym == defn.BooleanClass ) " Z"
211
+ else if (sym == defn.ByteClass ) " B"
212
+ else if (sym == defn.ShortClass ) " S"
213
+ else if (sym == defn.IntClass ) " I"
214
+ else if (sym == defn.LongClass ) " J"
215
+ else if (sym == defn.FloatClass ) " F"
216
+ else if (sym == defn.DoubleClass ) " D"
217
+ else if (sym == defn.CharClass ) " C"
218
+ else " L" + javaSig(elemType) + " ;"
219
+ (" [" * depth) + suffix
220
+ }
221
+ def javaSig (tpe : Type ): String = tpe match {
222
+ case tpe : JavaArrayType => javaArraySig(tpe)
223
+ case _ =>
224
+ // Take the flatten name of the class and the full package name
225
+ val pack = tpe.classSymbol.topLevelClass.owner
226
+ val packageName = if (pack == defn.EmptyPackageClass ) " " else pack.fullName + " ."
227
+ packageName + tpe.classSymbol.fullNameSeparated(FlatName ).toString
228
+ }
229
+
230
+ val sym = param.classSymbol
231
+ if (sym == defn.BooleanClass ) classOf [Boolean ]
232
+ else if (sym == defn.ByteClass ) classOf [Byte ]
233
+ else if (sym == defn.CharClass ) classOf [Char ]
234
+ else if (sym == defn.ShortClass ) classOf [Short ]
235
+ else if (sym == defn.IntClass ) classOf [Int ]
236
+ else if (sym == defn.LongClass ) classOf [Long ]
237
+ else if (sym == defn.FloatClass ) classOf [Float ]
238
+ else if (sym == defn.DoubleClass ) classOf [Double ]
239
+ else java.lang.Class .forName(javaSig(param), false , classLoader)
240
+ }
241
+ def getExtraParams (tp : Type ): List [Type ] = tp.widenDealias match {
242
+ case tp : AppliedType if defn.isImplicitFunctionType(tp) =>
243
+ // Call implicit function type direct method
244
+ tp.args.init.map(arg => TypeErasure .erasure(arg)) ::: getExtraParams(tp.args.last)
235
245
case _ => Nil
236
246
}
247
+ val extraParams = getExtraParams(sym.info.finalResultType)
248
+ val allParams = TypeErasure .erasure(sym.info) match {
249
+ case meth : MethodType => meth.paramInfos ::: extraParams
250
+ case _ => extraParams
251
+ }
252
+ allParams.map(paramClass)
237
253
}
238
254
239
255
/** Exception that stops interpretation if some issue is found */
@@ -253,9 +269,10 @@ object Splicer {
253
269
protected def interpretLiteral (value : Any )(implicit env : Env ): Boolean = true
254
270
protected def interpretVarargs (args : List [Boolean ])(implicit env : Env ): Boolean = args.forall(identity)
255
271
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)
257
- protected def interpretModuleAccess (fn : Tree )(implicit env : Env ): Boolean = true
258
- protected def interpretNew (fn : RefTree , args : => List [Boolean ])(implicit env : Env ): Boolean = args.forall(identity)
272
+ protected def interpretQuoteContext ()(implicit env : Env ): Boolean = true
273
+ protected def interpretStaticMethodCall (fn : Symbol , args : => List [Boolean ])(implicit env : Env ): Boolean = args.forall(identity)
274
+ protected def interpretModuleAccess (fn : Symbol )(implicit env : Env ): Boolean = true
275
+ protected def interpretNew (fn : Symbol , args : => List [Boolean ])(implicit env : Env ): Boolean = args.forall(identity)
259
276
260
277
def unexpectedTree (tree : tpd.Tree )(implicit env : Env ): Boolean = {
261
278
// Assuming that top-level splices can only be in inline methods
@@ -275,9 +292,9 @@ object Splicer {
275
292
protected def interpretLiteral (value : Any )(implicit env : Env ): Result
276
293
protected def interpretVarargs (args : List [Result ])(implicit env : Env ): Result
277
294
protected def interpretTastyContext ()(implicit env : Env ): Result
278
- protected def interpretStaticMethodCall (fn : Tree , args : => List [Result ])(implicit env : Env ): Result
279
- protected def interpretModuleAccess (fn : Tree )(implicit env : Env ): Result
280
- protected def interpretNew (fn : RefTree , args : => List [Result ])(implicit env : Env ): Result
295
+ protected def interpretStaticMethodCall (fn : Symbol , args : => List [Result ])(implicit env : Env ): Result
296
+ protected def interpretModuleAccess (fn : Symbol )(implicit env : Env ): Result
297
+ protected def interpretNew (fn : Symbol , args : => List [Result ])(implicit env : Env ): Result
281
298
protected def unexpectedTree (tree : Tree )(implicit env : Env ): Result
282
299
283
300
protected final def interpretTree (tree : Tree )(implicit env : Env ): Result = tree match {
@@ -295,10 +312,10 @@ object Splicer {
295
312
296
313
case Call (fn, args) =>
297
314
if (fn.symbol.isConstructor && fn.symbol.owner.owner.is(Package )) {
298
- interpretNew(fn, args.map(interpretTree))
315
+ interpretNew(fn.symbol , args.map(interpretTree))
299
316
} else if (fn.symbol.isStatic) {
300
- if (fn.symbol.is(Module )) interpretModuleAccess(fn)
301
- else interpretStaticMethodCall(fn, args.map(arg => interpretTree(arg)))
317
+ if (fn.symbol.is(Module )) interpretModuleAccess(fn.symbol )
318
+ else interpretStaticMethodCall(fn.symbol , args.map(arg => interpretTree(arg)))
302
319
} else if (env.contains(fn.name)) {
303
320
env(fn.name)
304
321
} else {
@@ -330,6 +347,8 @@ object Splicer {
330
347
331
348
object Call {
332
349
def unapply (arg : Tree ): Option [(RefTree , List [Tree ])] = arg match {
350
+ case Select (Call (fn, args), nme.apply) if defn.isImplicitFunctionType(fn.tpe.widenDealias.finalResultType) =>
351
+ Some ((fn, args))
333
352
case fn : RefTree => Some ((fn, Nil ))
334
353
case Apply (Call (fn, args1), args2) => Some ((fn, args1 ::: args2)) // TODO improve performance
335
354
case TypeApply (Call (fn, args), _) => Some ((fn, args))
0 commit comments