@@ -8,6 +8,7 @@ import dotty.tools.dotc.ast.Trees._
8
8
import dotty .tools .dotc .core .Constants ._
9
9
import dotty .tools .dotc .core .Contexts ._
10
10
import dotty .tools .dotc .core .Decorators ._
11
+ import dotty .tools .dotc .core .Flags ._
11
12
import dotty .tools .dotc .core .Names ._
12
13
import dotty .tools .dotc .core .Symbols ._
13
14
import dotty .tools .dotc .core .quoted .Quoted
@@ -82,20 +83,20 @@ class Interpreter(implicit ctx: Context) {
82
83
val constructor = getConstructor(clazz, paramClasses)
83
84
interpreted(constructor.newInstance(interpretedArgs : _* ))
84
85
85
- case _ : RefTree | _ : Apply if tree.symbol.isStatic =>
86
+ case _ : RefTree if tree.symbol.isStatic =>
86
87
val clazz = loadClass(tree.symbol.owner.companionModule.fullName)
88
+ val method = getMethod(clazz, tree.symbol.name, Nil )
89
+ interpreted(method.invoke(null ))
90
+
91
+ case tree : Apply =>
92
+ val evaluatedPrefix = if (tree.symbol.isStatic) null else interpretPrefix(tree, env)
93
+ val clazz =
94
+ if (tree.symbol.isStatic) loadClass(tree.symbol.owner.companionModule.fullName)
95
+ else evaluatedPrefix.getClass
87
96
val paramClasses = paramsSig(tree.symbol)
88
- val interpretedArgs = Array .newBuilder[Object ]
89
- def interpretArgs (tree : Tree ): Unit = tree match {
90
- case Apply (fn, args) =>
91
- interpretArgs(fn)
92
- args.foreach(arg => interpretedArgs += interpretTreeImpl(arg, env))
93
- case _ =>
94
- }
95
- interpretArgs(tree)
96
-
97
+ val interpretedArgs = interpretArgs(tree, env)
97
98
val method = getMethod(clazz, tree.symbol.name, paramClasses)
98
- interpreted(method.invoke(null , interpretedArgs.result() : _* ))
99
+ interpreted(method.invoke(evaluatedPrefix , interpretedArgs : _* ))
99
100
100
101
case tree : Ident if env.contains(tree.symbol) =>
101
102
env(tree.symbol)
@@ -114,13 +115,40 @@ class Interpreter(implicit ctx: Context) {
114
115
case Typed (expr, _) =>
115
116
interpretTreeImpl(expr, env)
116
117
118
+ // Getting the underlying value of a value class. The value class is evaluated as its boxed representation
119
+ // as values in the interpreter are `Object`s. Therefore we just get it from the enviroment as is.
120
+ case Select (qualifier, _)
121
+ if tree.symbol.owner.isValueClass && tree.symbol.is(ParamAccessor ) && env.contains(qualifier.symbol) =>
122
+ env(qualifier.symbol)
123
+
124
+ case SeqLiteral (elems, _) =>
125
+ elems.map(elem => interpretTreeImpl(elem, env))
126
+
117
127
case _ =>
118
128
// TODO Add more precise descriptions of why it could not be interpreted.
119
129
// This should be done after the full interpreter is implemented.
120
130
throw new StopInterpretation (s " Could not interpret ${tree.show}. Consider extracting logic into a helper def. " , tree.pos)
121
131
}
122
132
}
123
133
134
+ private def interpretArgs (tree : Tree , env : Env ): Seq [Object ] = {
135
+ val b = Seq .newBuilder[Object ]
136
+ def interpretArgs (tree : Tree ): Unit = tree match {
137
+ case Apply (fn, args) =>
138
+ interpretArgs(fn)
139
+ args.foreach(arg => b += interpretTreeImpl(arg, env))
140
+ case _ =>
141
+ }
142
+ interpretArgs(tree)
143
+ b.result()
144
+ }
145
+
146
+ private def interpretPrefix (tree : Tree , env : Env ): Object = tree match {
147
+ case Apply (qual, _) => interpretPrefix(qual, env)
148
+ case TypeApply (qual, _) => interpretPrefix(qual, env)
149
+ case Select (qual, _) => interpretTreeImpl(qual, env)
150
+ }
151
+
124
152
/** Interprets the statement and returns the updated environment */
125
153
private def interpretStat (stat : Tree , env : Env ): Env = stat match {
126
154
case tree : ValDef =>
0 commit comments