@@ -3,20 +3,16 @@ package interpreter
3
3
4
4
import java .io .{PrintWriter , StringWriter }
5
5
6
- import dotty .tools .dotc .ast .tpd
7
- import dotty .tools .dotc .ast .Trees ._
8
- import dotty .tools .dotc .core .Constants ._
9
6
import dotty .tools .dotc .core .Contexts ._
10
7
import dotty .tools .dotc .core .Decorators ._
11
8
import dotty .tools .dotc .core .Flags ._
12
9
import dotty .tools .dotc .core .Names ._
10
+ import dotty .tools .dotc .core .NameKinds ._
13
11
import dotty .tools .dotc .core .Symbols ._
14
- import dotty .tools .dotc .core .quoted .Quoted
15
12
import dotty .tools .dotc .util .Positions .Position
16
13
17
14
import scala .reflect .ClassTag
18
15
import java .net .URLClassLoader
19
- import java .lang .reflect .Constructor
20
16
import java .lang .reflect .Method
21
17
22
18
/** Tree interpreter that can interpret
@@ -28,7 +24,7 @@ import java.lang.reflect.Method
28
24
* The interpreter assumes that all calls in the trees are to code that was
29
25
* previously compiled and is present in the classpath of the current context.
30
26
*/
31
- class Interpreter (implicit ctx : Context ) {
27
+ class Interpreter (pos : Position )( implicit ctx : Context ) {
32
28
33
29
private [this ] val classLoader = {
34
30
val urls = ctx.settings.classpath.value.split(':' ).map(cp => java.nio.file.Paths .get(cp).toUri.toURL)
@@ -38,9 +34,9 @@ class Interpreter(implicit ctx: Context) {
38
34
/** Returns the interpreted result of interpreting the code a call to the symbol with default arguments.
39
35
* Return Some of the result or None if some error happen during the interpretation.
40
36
*/
41
- def interpretCallToSymbol [T ](sym : Symbol )(implicit pos : Position , ct : ClassTag [T ]): Option [T ] = {
37
+ def interpretCallToSymbol [T ](sym : Symbol )(implicit ct : ClassTag [T ]): Option [T ] = {
42
38
try {
43
- val clazz = loadClass (sym.owner.companionModule.fullName)(pos )
39
+ val ( clazz, instance) = loadModule (sym.owner)
44
40
val paramClasses = paramsSig(sym)
45
41
val interpretedArgs = paramClasses.map { clazz =>
46
42
if (clazz == classOf [Boolean ]) false .asInstanceOf [Object ]
@@ -54,9 +50,10 @@ class Interpreter(implicit ctx: Context) {
54
50
else null
55
51
}
56
52
53
+
57
54
val method = getMethod(clazz, sym.name, paramClasses)
58
55
59
- val o = stopIfRuntimeException(method.invoke(null , interpretedArgs : _* ))(pos )
56
+ val o = stopIfRuntimeException(method.invoke(instance , interpretedArgs : _* ))
60
57
61
58
o match {
62
59
case obj : T => Some (obj)
@@ -72,7 +69,18 @@ class Interpreter(implicit ctx: Context) {
72
69
}
73
70
}
74
71
75
- private def loadClass (name : Name )(implicit pos : Position ): Class [_] = {
72
+ private def loadModule (sym : Symbol ): (Class [_], Object ) = {
73
+ if (sym.owner.is(Package )) {
74
+ // is top level object
75
+ (loadClass(sym.companionModule.fullName), null )
76
+ } else {
77
+ // nested object in an object
78
+ val clazz = loadClass(sym.fullNameSeparated(FlatName ))
79
+ (clazz, clazz.newInstance().asInstanceOf [Object ])
80
+ }
81
+ }
82
+
83
+ private def loadClass (name : Name ): Class [_] = {
76
84
try classLoader.loadClass(name.toString)
77
85
catch {
78
86
case _ : ClassNotFoundException =>
@@ -81,7 +89,7 @@ class Interpreter(implicit ctx: Context) {
81
89
}
82
90
}
83
91
84
- private def getMethod (clazz : Class [_], name : Name , paramClasses : List [Class [_]])( implicit pos : Position ) : Method = {
92
+ private def getMethod (clazz : Class [_], name : Name , paramClasses : List [Class [_]]): Method = {
85
93
try clazz.getMethod(name.toString, paramClasses : _* )
86
94
catch {
87
95
case _ : NoSuchMethodException =>
@@ -90,7 +98,7 @@ class Interpreter(implicit ctx: Context) {
90
98
}
91
99
}
92
100
93
- private def stopIfRuntimeException [T ](thunk : => T )( implicit pos : Position ) : T = {
101
+ private def stopIfRuntimeException [T ](thunk : => T ): T = {
94
102
try thunk
95
103
catch {
96
104
case ex : RuntimeException =>
0 commit comments