@@ -8,6 +8,7 @@ import dotty.tools.dotc.ast.Trees._
88import dotty .tools .dotc .core .Constants ._
99import dotty .tools .dotc .core .Contexts ._
1010import dotty .tools .dotc .core .Decorators ._
11+ import dotty .tools .dotc .core .Flags ._
1112import dotty .tools .dotc .core .Names ._
1213import dotty .tools .dotc .core .Symbols ._
1314import dotty .tools .dotc .core .quoted .Quoted
@@ -82,20 +83,20 @@ class Interpreter(implicit ctx: Context) {
8283 val constructor = getConstructor(clazz, paramClasses)
8384 interpreted(constructor.newInstance(interpretedArgs : _* ))
8485
85- case _ : RefTree | _ : Apply if tree.symbol.isStatic =>
86+ case _ : RefTree if tree.symbol.isStatic =>
8687 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
8796 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)
9798 val method = getMethod(clazz, tree.symbol.name, paramClasses)
98- interpreted(method.invoke(null , interpretedArgs.result() : _* ))
99+ interpreted(method.invoke(evaluatedPrefix , interpretedArgs : _* ))
99100
100101 case tree : Ident if env.contains(tree.symbol) =>
101102 env(tree.symbol)
@@ -114,13 +115,40 @@ class Interpreter(implicit ctx: Context) {
114115 case Typed (expr, _) =>
115116 interpretTreeImpl(expr, env)
116117
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+
117127 case _ =>
118128 // TODO Add more precise descriptions of why it could not be interpreted.
119129 // This should be done after the full interpreter is implemented.
120130 throw new StopInterpretation (s " Could not interpret ${tree.show}. Consider extracting logic into a helper def. " , tree.pos)
121131 }
122132 }
123133
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+
124152 /** Interprets the statement and returns the updated environment */
125153 private def interpretStat (stat : Tree , env : Env ): Env = stat match {
126154 case tree : ValDef =>
0 commit comments